Skip to content

Commit

Permalink
Refactor how we deal with configuration.
Browse files Browse the repository at this point in the history
In particular:

* Move veil's, veil-verify's, and veil-proxy's configuration to the
  `config` package.

* Add `validate.Object`, which validates a given object and turns
  validation errors into joined errors.

* Unify the way we handle configuration across our three command line
  tools.
  • Loading branch information
NullHypothesis committed Dec 25, 2024
1 parent 3720d9f commit ebb5332
Show file tree
Hide file tree
Showing 19 changed files with 390 additions and 242 deletions.
25 changes: 12 additions & 13 deletions cmd/veil-proxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,16 @@ import (
"os/signal"
"sync"

"github.com/Amnesic-Systems/veil/internal/config"
"github.com/Amnesic-Systems/veil/internal/errs"
"github.com/Amnesic-Systems/veil/internal/net/nat"
"github.com/Amnesic-Systems/veil/internal/net/proxy"
"github.com/Amnesic-Systems/veil/internal/net/tun"
"github.com/Amnesic-Systems/veil/internal/types/validate"
"github.com/mdlayher/vsock"
)

type config struct {
profile bool
port int
}

func parseFlags(out io.Writer, args []string) (_ *config, err error) {
func parseFlags(out io.Writer, args []string) (_ *config.VeilProxy, err error) {
defer errs.Wrap(&err, "failed to parse flags")

fs := flag.NewFlagSet("veil-proxy", flag.ContinueOnError)
Expand All @@ -35,7 +32,7 @@ func parseFlags(out io.Writer, args []string) (_ *config, err error) {
false,
"Enable profiling.",
)
port := fs.Int(
port := fs.Uint(
"port",
1024,
"VSOCK port that the enclave connects to.",
Expand All @@ -44,10 +41,12 @@ func parseFlags(out io.Writer, args []string) (_ *config, err error) {
return nil, err
}

return &config{
profile: *profile,
port: *port,
}, nil
// Build and validate the configuration.
cfg := &config.VeilProxy{
Profile: *profile,
Port: uint32(*port),
}
return cfg, validate.Object(cfg)
}

func listenVSOCK(port uint32) (_ net.Listener, err error) {
Expand Down Expand Up @@ -118,7 +117,7 @@ func run(ctx context.Context, out io.Writer, args []string) (origErr error) {

// Create a VSOCK listener that listens for incoming connections from the
// enclave.
ln, err := listenVSOCK(uint32(cfg.port))
ln, err := listenVSOCK(cfg.Port)
if err != nil {
return err
}
Expand All @@ -127,7 +126,7 @@ func run(ctx context.Context, out io.Writer, args []string) (origErr error) {
}()

// If desired, set up a Web server for the profiler.
if cfg.profile {
if cfg.Profile {
go func() {
const hostPort = "localhost:6060"
log.Printf("Starting profiling Web server at: http://%s", hostPort)
Expand Down
7 changes: 4 additions & 3 deletions cmd/veil-verify/attestation.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (

"github.com/fatih/color"

"github.com/Amnesic-Systems/veil/internal/config"
"github.com/Amnesic-Systems/veil/internal/enclave"
"github.com/Amnesic-Systems/veil/internal/enclave/nitro"
"github.com/Amnesic-Systems/veil/internal/enclave/noop"
Expand All @@ -33,7 +34,7 @@ var (

func attestEnclave(
ctx context.Context,
cfg *config,
cfg *config.VeilVerify,
pcrs enclave.PCR,
) (err error) {
defer errs.WrapErr(&err, errFailedToAttest)
Expand All @@ -44,7 +45,7 @@ func attestEnclave(
return err
}

req, err := buildReq(ctx, cfg.addr, nonce)
req, err := buildReq(ctx, cfg.Addr, nonce)
if err != nil {
return err
}
Expand Down Expand Up @@ -76,7 +77,7 @@ func attestEnclave(
// talking to an enclave. The nonce provides assurance that we are talking
// to an alive enclave (instead of a replayed attestation document).
var attester enclave.Attester = nitro.NewAttester()
if cfg.testing {
if cfg.Testing {
attester = noop.NewAttester()
}
doc, err := attester.Verify(&rawDoc, nonce)
Expand Down
11 changes: 6 additions & 5 deletions cmd/veil-verify/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"path"

"github.com/Amnesic-Systems/veil/internal/addr"
"github.com/Amnesic-Systems/veil/internal/config"
"github.com/Amnesic-Systems/veil/internal/enclave"
"github.com/Amnesic-Systems/veil/internal/errs"
"github.com/docker/docker/api/types"
Expand Down Expand Up @@ -57,7 +58,7 @@ func removeContainer(cli *client.Client, id string) {
func buildEnclaveImage(
ctx context.Context,
cli *client.Client,
cfg *config,
cfg *config.VeilVerify,
out io.Writer,
) (err error) {
defer errs.Wrap(&err, "failed to build enclave image")
Expand All @@ -80,7 +81,7 @@ func buildEnclaveImage(
Tty: true,
Image: builderImage,
Cmd: []string{
"--dockerfile", cfg.dockerfile,
"--dockerfile", cfg.Dockerfile,
"--reproducible",
"--no-push",
"--log-format", "text",
Expand All @@ -96,7 +97,7 @@ func buildEnclaveImage(
Mounts: []mount.Mount{
{
Type: mount.TypeBind,
Source: cfg.dir,
Source: cfg.Dir,
Target: "/workspace",
},
},
Expand Down Expand Up @@ -166,13 +167,13 @@ func getContainerExitCode(
func loadEnclaveImage(
ctx context.Context,
cli *client.Client,
cfg *config,
cfg *config.VeilVerify,
verbose io.Writer,
) (err error) {
defer errs.Wrap(&err, "failed to load enclave image")

// Read the tar image.
file, err := os.Open(path.Join(cfg.dir, enclaveTarImage))
file, err := os.Open(path.Join(cfg.Dir, enclaveTarImage))
if err != nil {
return err
}
Expand Down
44 changes: 12 additions & 32 deletions cmd/veil-verify/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,21 @@ import (
"context"
"errors"
"flag"
"fmt"
"io"
"log"
"os"
"os/signal"
"path"

"github.com/docker/docker/client"

"github.com/Amnesic-Systems/veil/internal/config"
"github.com/Amnesic-Systems/veil/internal/errs"
"github.com/Amnesic-Systems/veil/internal/types/validate"
)

var errFailedToParse = errors.New("failed to parse flags")

type config struct {
addr string
dir string
dockerfile string
verbose bool
testing bool
}

func parseFlags(out io.Writer, args []string) (_ *config, err error) {
func parseFlags(out io.Writer, args []string) (_ *config.VeilVerify, err error) {
defer errs.WrapErr(&err, errFailedToParse)

fs := flag.NewFlagSet("veil-verify", flag.ContinueOnError)
Expand Down Expand Up @@ -61,27 +53,15 @@ func parseFlags(out io.Writer, args []string) (_ *config, err error) {
return nil, err
}

// Ensure that required arguments are set.
if *addr == "" {
return nil, errors.New("flag -addr must be provided")
}
if *dir == "" {
return nil, errors.New("flag -dir must be provided")
}

// Make sure that the Dockerfile relative to the given directory exists.
p := path.Join(*dir, *dockerfile)
if _, err := os.Stat(p); err != nil {
return nil, fmt.Errorf("given Dockerfile %q does not exist", p)
// Build and validate the configuration.
cfg := &config.VeilVerify{
Addr: *addr,
Dir: *dir,
Dockerfile: *dockerfile,
Testing: *testing,
Verbose: *verbose,
}

return &config{
addr: *addr,
dir: *dir,
dockerfile: *dockerfile,
testing: *testing,
verbose: *verbose,
}, nil
return cfg, validate.Object(cfg)
}

func run(ctx context.Context, out io.Writer, args []string) error {
Expand All @@ -95,7 +75,7 @@ func run(ctx context.Context, out io.Writer, args []string) error {

// By default, we discard Docker's logs but we print them in verbose mode.
writer := io.Discard
if cfg.verbose {
if cfg.Verbose {
writer = log.Writer()
}

Expand Down
22 changes: 7 additions & 15 deletions cmd/veil/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package main
import (
"bufio"
"context"
"errors"
"flag"
"fmt"
"io"
Expand All @@ -23,14 +22,15 @@ import (
"github.com/Amnesic-Systems/veil/internal/httpx"
"github.com/Amnesic-Systems/veil/internal/service"
"github.com/Amnesic-Systems/veil/internal/tunnel"
"github.com/Amnesic-Systems/veil/internal/types/validate"
)

const (
defaultExtPort = 8443
defaultIntPort = 8080
)

func parseFlags(out io.Writer, args []string) (*config.Config, error) {
func parseFlags(out io.Writer, args []string) (*config.Veil, error) {
fs := flag.NewFlagSet("veil", flag.ContinueOnError)
fs.SetOutput(out)

Expand Down Expand Up @@ -103,8 +103,8 @@ func parseFlags(out io.Writer, args []string) (*config.Config, error) {
}
}

// Build and validate the config.
return &config.Config{
// Build and validate the configuration.
cfg := &config.Veil{
AppCmd: *appCmd,
AppWebSrv: u,
Debug: *debug,
Expand All @@ -116,7 +116,8 @@ func parseFlags(out io.Writer, args []string) (*config.Config, error) {
SilenceApp: *silenceApp,
Testing: *testing,
WaitForApp: *waitForApp,
}, nil
}
return cfg, validate.Object(cfg)
}

func run(ctx context.Context, out io.Writer, args []string) (err error) {
Expand All @@ -135,15 +136,6 @@ func run(ctx context.Context, out io.Writer, args []string) (err error) {
return err
}

// Validate the configuration.
if problems := cfg.Validate(ctx); len(problems) > 0 {
err := errors.New("invalid configuration")
for field, problem := range problems {
err = errors.Join(err, fmt.Errorf("field %s: %v", field, problem))
}
return err
}

// Run the application command, if specified.
if cfg.AppCmd != "" {
go func() {
Expand All @@ -167,7 +159,7 @@ func run(ctx context.Context, out io.Writer, args []string) (err error) {
return nil
}

func eventuallyRunAppCmd(ctx context.Context, cfg *config.Config, cmd string) (err error) {
func eventuallyRunAppCmd(ctx context.Context, cfg *config.Veil, cmd string) (err error) {
defer errs.Wrap(&err, "failed to run app command")

// Wait for the internal service to be ready.
Expand Down
2 changes: 1 addition & 1 deletion cmd/veil/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ func TestRunApp(t *testing.T) {

// Decode the configuration file and verify that the application
// command is identical to what we just ran.
var cfg config.Config
var cfg config.Veil
require.NoError(t, json.Unmarshal(content, &cfg))
require.Equal(t, c.command, cfg.AppCmd)
})
Expand Down
Loading

0 comments on commit ebb5332

Please sign in to comment.