diff --git a/bin/vproxy/flags.go b/bin/vproxy/flags.go index dbf0d05..950aa95 100644 --- a/bin/vproxy/flags.go +++ b/bin/vproxy/flags.go @@ -122,6 +122,14 @@ func parseFlags() { Action: printCAROOT, Before: loadClientConfig, Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "create", + Usage: "Initialize and install the CAROOT (will not overwrite existing files)", + }, + &cli.BoolFlag{ + Name: "uninstall", + Usage: "Uninstall the CAROOT (will not remove files)", + }, &cli.BoolFlag{ Name: "default", Usage: "Get the default CAROOT path (ignoring any config or env vars)", diff --git a/bin/vproxy/main.go b/bin/vproxy/main.go index 843a76c..94d56d3 100644 --- a/bin/vproxy/main.go +++ b/bin/vproxy/main.go @@ -6,9 +6,11 @@ import ( "fmt" "net/http" "os" + "path/filepath" "regexp" "strings" + "github.com/jittering/truststore" "github.com/jittering/vproxy" "github.com/urfave/cli/v2" ) @@ -116,6 +118,14 @@ func listClients(c *cli.Context) error { } func printCAROOT(c *cli.Context) error { + if c.Bool("create") { + return createCAROOT() + } + + if c.Bool("uninstall") { + return uninstallCAROOT() + } + if c.Bool("default") { os.Unsetenv("CAROOT_PATH") } @@ -123,6 +133,65 @@ func printCAROOT(c *cli.Context) error { return nil } +func createCAROOT() error { + // create new caroot, if needed + path := vproxy.CARootPath() + os.Setenv("CAROOT", path) + + if fileExists(filepath.Join(path, "rootCA.pem")) { + fmt.Printf("CA already exists at %s\n", path) + } else { + fmt.Printf("creating new CA at %s\n", path) + } + + fmt.Printf("\n >> NOTE: you may be prompted to enter your sudo password <<\n\n") + + err := os.MkdirAll(path, 0755) + if err != nil { + return fmt.Errorf("failed to create CA path: %v", err) + } + + truststore.Print = true + err = vproxy.InitTrustStore() + if err != nil { + return fmt.Errorf("failed to init CA: %v", err) + } + + err = vproxy.InstallTrustStore() + if err != nil { + return fmt.Errorf("failed to install CA: %v", err) + } + + return nil +} + +func uninstallCAROOT() error { + path := vproxy.CARootPath() + os.Setenv("CAROOT", path) + + if !fileExists(filepath.Join(path, "rootCA.pem")) { + fmt.Printf("CA not found at %s\n", path) + return nil + } + + fmt.Printf("\n >> NOTE: you may be prompted to enter your sudo password <<\n\n") + + truststore.Print = true + err := vproxy.InitTrustStore() + if err != nil { + return fmt.Errorf("failed to load CA: %v", err) + } + + err = vproxy.UninstallTrustStore() + if err != nil { + return fmt.Errorf("failed to uninstall CA: %v", err) + } + + fmt.Println("successfully uninstalled CA") + + return nil +} + func main() { parseFlags() } diff --git a/cert.go b/cert.go index d83d3ae..13f60f6 100644 --- a/cert.go +++ b/cert.go @@ -1,6 +1,7 @@ package vproxy import ( + "fmt" "log" "os" "path/filepath" @@ -17,6 +18,20 @@ func InitTrustStore() error { return err } +func InstallTrustStore() error { + if ts == nil { + return fmt.Errorf("error: truststore not initialized") + } + return ts.Install() +} + +func UninstallTrustStore() error { + if ts == nil { + return fmt.Errorf("error: truststore not initialized") + } + return ts.Uninstall() +} + func CARootPath() string { if cp := os.Getenv("CAROOT_PATH"); cp != "" { // override from env diff --git a/go.mod b/go.mod index 497090c..8b1326d 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.15 require ( github.com/cenkalti/backoff/v4 v4.1.1 - github.com/jittering/truststore v0.0.0-20211027133117-2fe762cab260 + github.com/jittering/truststore v0.0.0-20211027161121-f6ab96800561 github.com/mattn/go-isatty v0.0.14 github.com/mitchellh/go-homedir v1.1.0 github.com/pelletier/go-toml v1.9.4 diff --git a/go.sum b/go.sum index 836a301..2d658eb 100644 --- a/go.sum +++ b/go.sum @@ -23,6 +23,8 @@ github.com/jittering/truststore v0.0.0-20211026192954-23f65d32fa19 h1:pHO6m29RxL github.com/jittering/truststore v0.0.0-20211026192954-23f65d32fa19/go.mod h1:1Oqxux2zlUnu3LTJMyO70ndQ6vrITR/cXOrOeswbgN4= github.com/jittering/truststore v0.0.0-20211027133117-2fe762cab260 h1:U28Z52aCN7NSTuUs1y+4TaKVo3hYzfhX1CtkLEGkVdU= github.com/jittering/truststore v0.0.0-20211027133117-2fe762cab260/go.mod h1:1Oqxux2zlUnu3LTJMyO70ndQ6vrITR/cXOrOeswbgN4= +github.com/jittering/truststore v0.0.0-20211027161121-f6ab96800561 h1:nX/9o1W4gZkF0Lv7LLHzY52yAMcSOeDfu0n3IpZ3T6A= +github.com/jittering/truststore v0.0.0-20211027161121-f6ab96800561/go.mod h1:1Oqxux2zlUnu3LTJMyO70ndQ6vrITR/cXOrOeswbgN4= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=