diff --git a/ziti/cmd/console/console.go b/ziti/cmd/console/console.go index 2986e2be0..189cb0509 100644 --- a/ziti/cmd/console/console.go +++ b/ziti/cmd/console/console.go @@ -104,16 +104,18 @@ func (o *ConsoleOptions) Run() error { return err } + // Resolve the certificate before binding so a cert error doesn't leave the listener open or + // claim the port. + cert, err := o.serverCertificate() + if err != nil { + return err + } + listenAddr := net.JoinHostPort(o.BindAddress, fmt.Sprintf("%d", o.Port)) rawLn, err := net.Listen("tcp", listenAddr) if err != nil { return fmt.Errorf("failed to listen on %s: %w", listenAddr, err) } - - cert, err := o.serverCertificate() - if err != nil { - return err - } ln := tls.NewListener(rawLn, &tls.Config{Certificates: []tls.Certificate{cert}}) // ZAC bundles ship with , so the assets the browser requests are prefixed diff --git a/ziti/cmd/console/ops_configure.go b/ziti/cmd/console/ops_configure.go index 2488967b3..61d90b001 100644 --- a/ziti/cmd/console/ops_configure.go +++ b/ziti/cmd/console/ops_configure.go @@ -95,6 +95,11 @@ func (o *ConfigureOptions) Run() error { if o.Path == "" { return fmt.Errorf("--path must not be empty") } + // The controller's spa binding rejects a path with interior separators, so fail here rather + // than write a config the controller will refuse to load. + if strings.ContainsAny(o.Path, "/\\") { + return fmt.Errorf("--path %q must be a single segment with no '/' or '\\' separators", o.Path) + } reader := bufio.NewReader(o.In) if err := o.ensureLocationAndAssets(reader); err != nil {