From d382d09918d2f6c0e45766dbc082dcdc4fe52fa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Teubel=20Gy=C3=B6rgy?= Date: Wed, 20 Nov 2019 17:18:19 +0100 Subject: [PATCH] Pass vault name and requested password type to askpass process --- doc/man/vaulted.1 | 11 +++++++++++ doc/vaulted.1.md | 11 +++++++++++ steward.go | 30 ++++++++++++++++++++++++------ 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/doc/man/vaulted.1 b/doc/man/vaulted.1 index de9403f..d30d351 100644 --- a/doc/man/vaulted.1 +++ b/doc/man/vaulted.1 @@ -115,6 +115,17 @@ intended to be shown to the user. The askpass implementation then writes the password to \fB\fCstdout\fR and returns a success code (0). If a failure code (non\-0) is returned, the password input is aborted. .PP +The vault name, requested secret type (password, MFA token etc.) and password +request reason is passed to the askpass process in the environment variables +\fB\fCVAULTED_ENV\fR, \fB\fCVAULTED_PASSWORD_TYPE\fR and \fB\fCVAULTED_PASSWORD_REASON\fR +respectively. +.PP +Valid values for \fB\fCVAULTED_PASSWORD_TYPE\fR are: \fB\fCpassword\fR, \fB\fClegacypassword\fR or +\fB\fCmfatoken\fR\&. +.PP +Valid values for \fB\fCVAULTED_PASSWORD_REASON\fR are: \fB\fCnew\fR, \fB\fCnomatch\fR, \fB\fCconfirm\fR or +the empty string if \fB\fCVAULTED_PASSWORD_TYPE\fR is not \fB\fCpassword\fR\&. +.PP Vaulted is intended to integrate seamlessly with existing askpass implementations (e.g. \fB\fCssh\-askpass\fR). .PP diff --git a/doc/vaulted.1.md b/doc/vaulted.1.md index cf9f7e1..faa9089 100644 --- a/doc/vaulted.1.md +++ b/doc/vaulted.1.md @@ -106,6 +106,17 @@ intended to be shown to the user. The askpass implementation then writes the password to `stdout` and returns a success code (0). If a failure code (non-0) is returned, the password input is aborted. +The vault name, requested secret type (password, MFA token etc.) and password +request reason is passed to the askpass process in the environment variables +`VAULTED_ENV`, `VAULTED_PASSWORD_TYPE` and `VAULTED_PASSWORD_REASON` +respectively. + +Valid values for `VAULTED_PASSWORD_TYPE` are: `password`, `legacypassword` or +`mfatoken`. + +Valid values for `VAULTED_PASSWORD_REASON` are: `new`, `nomatch`, `confirm` or +the empty string if `VAULTED_PASSWORD_TYPE` is not `password`. + Vaulted is intended to integrate seamlessly with existing askpass implementations (e.g. `ssh-askpass`). diff --git a/steward.go b/steward.go index e9cf7de..e13f8bf 100644 --- a/steward.go +++ b/steward.go @@ -13,6 +13,16 @@ import ( "github.com/miquella/vaulted/lib/legacy" ) +const ( + PASSWORD_TYPE_PASSWORD = "password" + PASSWORD_TYPE_LEGACY_PASSWORD = "legacypassword" + PASSWORD_TYPE_MFATOKEN = "mfatoken" + + PASSWORD_REASON_NEW = "new" + PASSWORD_REASON_NOMATCH = "nomatch" + PASSWORD_REASON_CONFIRM = "confirm" +) + func NewSteward() vaulted.Steward { if askpass, present := os.LookupEnv("VAULTED_ASKPASS"); present { return &AskPassSteward{ @@ -56,18 +66,21 @@ func (t *AskPassSteward) GetPassword(operation vaulted.Operation, name string) ( switch operation { case vaulted.SealOperation: for firstTry := false; ; firstTry = true { + var passwordreason string var prompt string if firstTry { + passwordreason = PASSWORD_REASON_NEW prompt = fmt.Sprintf("'%s' new password: ", name) } else { + passwordreason = PASSWORD_REASON_NOMATCH prompt = fmt.Sprintf("'%s' new password (passwords didn't match): ", name) } - password, err := t.askpass(prompt) + password, err := t.askpass(name, PASSWORD_TYPE_PASSWORD, passwordreason, prompt) if err != nil { return "", err } - confirm, err := t.askpass(fmt.Sprintf("'%s' confirm password: ", name)) + confirm, err := t.askpass(name, PASSWORD_TYPE_PASSWORD, PASSWORD_REASON_CONFIRM, fmt.Sprintf("'%s' confirm password: ", name)) if err != nil { return "", err } @@ -78,19 +91,24 @@ func (t *AskPassSteward) GetPassword(operation vaulted.Operation, name string) ( } case legacy.LegacyOperation: - return t.askpass("Legacy Password: ") + return t.askpass(name, PASSWORD_TYPE_LEGACY_PASSWORD, "", "Legacy Password: ") default: - return t.askpass(fmt.Sprintf("'%s' password: ", name)) + return t.askpass(name, PASSWORD_TYPE_PASSWORD, "", fmt.Sprintf("'%s' password: ", name)) } } func (t *AskPassSteward) GetMFAToken(name string) (string, error) { - return t.askpass(fmt.Sprintf("'%s' MFA token: ", name)) + return t.askpass(name, PASSWORD_TYPE_MFATOKEN, "", fmt.Sprintf("'%s' MFA token: ", name)) } -func (t *AskPassSteward) askpass(prompt string) (string, error) { +func (t *AskPassSteward) askpass(name string, passwordtype string, reason string, prompt string) (string, error) { cmd := exec.Command(t.Command, prompt) + cmd.Env = append(os.Environ(), + "VAULTED_ENV="+name, + "VAULTED_PASSWORD_TYPE="+passwordtype, + "VAULTED_PASSWORD_REASON="+reason, + ) output, err := cmd.Output() if err != nil { return "", ErrNoPasswordEntered