diff --git a/internal/cli/requestor.go b/internal/cli/requestor.go index 6f16788..a2762b2 100644 --- a/internal/cli/requestor.go +++ b/internal/cli/requestor.go @@ -25,7 +25,7 @@ func newRequestor(ccs *components.Components) (jw.Model, error) { cfg := ccs.Config.Server() endpoint := &requestor.Endpoint{ - URL: fmt.Sprintf("http://localhost:%d", cfg.Port), + URL: fmt.Sprintf("https://localhost:%d", cfg.Port), Username: username, Password: password, } diff --git a/internal/config/data/server.go b/internal/config/data/server.go index bba54e2..f3b3cea 100644 --- a/internal/config/data/server.go +++ b/internal/config/data/server.go @@ -8,9 +8,27 @@ package data const _defaultServerPort = 65530 +// Cli AFAIRE. +type Cli struct { + CA string + Cert string + Key string +} + +// TLS AFAIRE. +type TLS struct { + Host string + CA string + Cert string + Key string + AuthType int + Cli *Cli +} + // Server AFAIRE. type Server struct { Port int + TLS *TLS } func (s *Server) validate() error { diff --git a/internal/server/server.go b/internal/server/server.go index 4331e8b..3122cb7 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -8,30 +8,86 @@ package server import ( "context" + "crypto/tls" + "crypto/x509" "fmt" + "io/ioutil" "log" "net/http" "time" + "forge.chapril.org/mls-361/errors" "forge.chapril.org/mls-361/uuid" "forge.chapril.org/armen/armen/internal/components" + "forge.chapril.org/armen/armen/internal/config/data" ) type server struct { logger components.Logger server *http.Server + tls bool + cert string + key string } -func newServer(logger components.Logger) *server { +func newServer(logger components.Logger, tls bool) *server { return &server{ logger: logger, + tls: tls, } } +func (cs *server) getTLSConfig(d *data.TLS) (*tls.Config, error) { + if !cs.tls { + return nil, nil + } + + cs.cert = d.Cert + cs.key = d.Key + + var certPool *x509.CertPool + authType := tls.NoClientCert + + if d.AuthType != 0 { + buf, err := ioutil.ReadFile(d.CA) + if err != nil { + return nil, errors.WithMessage(err, "unable to read this file", "file", d.CA) ////////////////////////////// + } + + certPool = x509.NewCertPool() + certPool.AppendCertsFromPEM(buf) + + switch d.AuthType { + case 1: + authType = tls.RequestClientCert + case 2: + authType = tls.RequireAnyClientCert + case 3: + authType = tls.VerifyClientCertIfGiven + case 4: + authType = tls.RequireAndVerifyClientCert + } + } + + cfg := &tls.Config{ + ServerName: d.Host, + ClientAuth: authType, + ClientCAs: certPool, + MinVersion: tls.VersionTLS12, + } + + return cfg, nil +} + func Build(ccs *components.Components) (components.Server, error) { - cs := newServer(ccs.Logger.NewLogger(uuid.New(), "server")) cfg := ccs.Config.Server() + cs := newServer(ccs.Logger.NewLogger(uuid.New(), "server"), cfg.TLS != nil) + + tlsConfig, err := cs.getTLSConfig(cfg.TLS) + if err != nil { + return nil, errors.WithMessage(err, "Cannot configure TLS") //////////////////////////////////////////////////// + } cs.server = &http.Server{ Addr: fmt.Sprintf(":%d", cfg.Port), @@ -40,6 +96,7 @@ func Build(ccs *components.Components) (components.Server, error) { IdleTimeout: 1 * time.Minute, ReadTimeout: 5 * time.Second, WriteTimeout: 10 * time.Second, + TLSConfig: tlsConfig, } return cs, nil @@ -49,7 +106,14 @@ func Build(ccs *components.Components) (components.Server, error) { func (cs *server) Run() error { cs.logger.Info("Started") //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: - err := cs.server.ListenAndServe() + var err error + + if cs.tls { + err = cs.server.ListenAndServeTLS(cs.cert, cs.key) + } else { + err = cs.server.ListenAndServe() + } + if err == http.ErrServerClosed { return nil }