diff --git a/command/unseal.go b/command/unseal.go index fcad9ddc37..5528a72ab4 100644 --- a/command/unseal.go +++ b/command/unseal.go @@ -11,6 +11,10 @@ import ( // UnsealCommand is a Command that unseals the vault. type UnsealCommand struct { Meta + + // Key can be used to pre-seed the key. If it is set, it will not + // be asked with the `password` helper. + Key string } func (c *UnsealCommand) Run(args []string) int { @@ -29,17 +33,20 @@ func (c *UnsealCommand) Run(args []string) int { return 2 } - fmt.Printf("Key (will be hidden): ") - value, err := password.Read(os.Stdin) - if err != nil { - c.Ui.Error(fmt.Sprintf( - "Error attempting to ask for password. The raw error message\n"+ - "is shown below, but the most common reason for this error is\n"+ - "that you attempted to pipe a value into unseal. This is not\n"+ - "allowed. The value must be typed directly into the command\n"+ - "after it is executed.\n\n"+ - "Raw error: %s", err)) - return 1 + value := c.Key + if value == "" { + fmt.Printf("Key (will be hidden): ") + value, err = password.Read(os.Stdin) + if err != nil { + c.Ui.Error(fmt.Sprintf( + "Error attempting to ask for password. The raw error message\n"+ + "is shown below, but the most common reason for this error is\n"+ + "that you attempted to pipe a value into unseal. This is not\n"+ + "allowed. The value must be typed directly into the command\n"+ + "after it is executed.\n\n"+ + "Raw error: %s", err)) + return 1 + } } status, err := client.Sys().Unseal(strings.TrimSpace(value)) @@ -59,6 +66,7 @@ func (c *UnsealCommand) Run(args []string) int { status.T, status.Progress, )) + return 0 } diff --git a/command/unseal_test.go b/command/unseal_test.go new file mode 100644 index 0000000000..e21733ede6 --- /dev/null +++ b/command/unseal_test.go @@ -0,0 +1,38 @@ +package command + +import ( + "encoding/hex" + "testing" + + "github.com/hashicorp/vault/http" + "github.com/hashicorp/vault/vault" + "github.com/mitchellh/cli" +) + +func TestUnseal(t *testing.T) { + core := vault.TestCore(t) + keys := vault.TestCoreInit(t, core) + ln, addr := http.TestServer(t, core) + defer ln.Close() + + ui := new(cli.MockUi) + c := &UnsealCommand{ + Key: hex.EncodeToString(keys[0]), + Meta: Meta{ + Ui: ui, + }, + } + + args := []string{"-address", addr} + if code := c.Run(args); code != 0 { + t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) + } + + sealed, err := core.Sealed() + if err != nil { + t.Fatalf("err: %s", err) + } + if sealed { + t.Fatal("should not be sealed") + } +}