diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 48ce7dbe213..cc4c30ff8ea 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -1698,7 +1698,7 @@ }, { "ImportPath": "github.com/howeyc/gopass", - "Rev": "3ca23474a7c7203e0a0a070fd33508f6efdb9b3d" + "Rev": "bf9dde6d0d2c004a008c27aaee91170c786f6db8" }, { "ImportPath": "github.com/imdario/mergo", diff --git a/staging/src/k8s.io/apiserver/Godeps/Godeps.json b/staging/src/k8s.io/apiserver/Godeps/Godeps.json index b47c26f6015..d27fa92eecd 100644 --- a/staging/src/k8s.io/apiserver/Godeps/Godeps.json +++ b/staging/src/k8s.io/apiserver/Godeps/Godeps.json @@ -468,7 +468,7 @@ }, { "ImportPath": "github.com/howeyc/gopass", - "Rev": "3ca23474a7c7203e0a0a070fd33508f6efdb9b3d" + "Rev": "bf9dde6d0d2c004a008c27aaee91170c786f6db8" }, { "ImportPath": "github.com/imdario/mergo", diff --git a/staging/src/k8s.io/client-go/Godeps/Godeps.json b/staging/src/k8s.io/client-go/Godeps/Godeps.json index d38718f955b..bc4dcc53c12 100644 --- a/staging/src/k8s.io/client-go/Godeps/Godeps.json +++ b/staging/src/k8s.io/client-go/Godeps/Godeps.json @@ -148,7 +148,7 @@ }, { "ImportPath": "github.com/howeyc/gopass", - "Rev": "3ca23474a7c7203e0a0a070fd33508f6efdb9b3d" + "Rev": "bf9dde6d0d2c004a008c27aaee91170c786f6db8" }, { "ImportPath": "github.com/imdario/mergo", diff --git a/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json b/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json index 0d7740085d2..90ea20d8082 100644 --- a/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json +++ b/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json @@ -224,7 +224,7 @@ }, { "ImportPath": "github.com/howeyc/gopass", - "Rev": "3ca23474a7c7203e0a0a070fd33508f6efdb9b3d" + "Rev": "bf9dde6d0d2c004a008c27aaee91170c786f6db8" }, { "ImportPath": "github.com/imdario/mergo", diff --git a/staging/src/k8s.io/kube-apiextensions-server/Godeps/Godeps.json b/staging/src/k8s.io/kube-apiextensions-server/Godeps/Godeps.json index 9fc536f2bec..433aebd206a 100644 --- a/staging/src/k8s.io/kube-apiextensions-server/Godeps/Godeps.json +++ b/staging/src/k8s.io/kube-apiextensions-server/Godeps/Godeps.json @@ -216,7 +216,7 @@ }, { "ImportPath": "github.com/howeyc/gopass", - "Rev": "3ca23474a7c7203e0a0a070fd33508f6efdb9b3d" + "Rev": "bf9dde6d0d2c004a008c27aaee91170c786f6db8" }, { "ImportPath": "github.com/imdario/mergo", diff --git a/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json b/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json index ddae55cc8e0..32dc620efa9 100644 --- a/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json +++ b/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json @@ -216,7 +216,7 @@ }, { "ImportPath": "github.com/howeyc/gopass", - "Rev": "3ca23474a7c7203e0a0a070fd33508f6efdb9b3d" + "Rev": "bf9dde6d0d2c004a008c27aaee91170c786f6db8" }, { "ImportPath": "github.com/imdario/mergo", diff --git a/vendor/github.com/howeyc/gopass/pass.go b/vendor/github.com/howeyc/gopass/pass.go index 31c853ae2e2..f5bd5a51a8c 100644 --- a/vendor/github.com/howeyc/gopass/pass.go +++ b/vendor/github.com/howeyc/gopass/pass.go @@ -7,9 +7,14 @@ import ( "os" ) -var defaultGetCh = func() (byte, error) { +type FdReader interface { + io.Reader + Fd() uintptr +} + +var defaultGetCh = func(r io.Reader) (byte, error) { buf := make([]byte, 1) - if n, err := os.Stdin.Read(buf); n == 0 || err != nil { + if n, err := r.Read(buf); n == 0 || err != nil { if err != nil { return 0, err } @@ -28,9 +33,10 @@ var ( ) // getPasswd returns the input read from terminal. +// If prompt is not empty, it will be output as a prompt to the user // If masked is true, typing will be matched by asterisks on the screen. // Otherwise, typing will echo nothing. -func getPasswd(masked bool) ([]byte, error) { +func getPasswd(prompt string, masked bool, r FdReader, w io.Writer) ([]byte, error) { var err error var pass, bs, mask []byte if masked { @@ -38,26 +44,33 @@ func getPasswd(masked bool) ([]byte, error) { mask = []byte("*") } - if isTerminal(os.Stdin.Fd()) { - if oldState, err := makeRaw(os.Stdin.Fd()); err != nil { + if isTerminal(r.Fd()) { + if oldState, err := makeRaw(r.Fd()); err != nil { return pass, err } else { - defer restore(os.Stdin.Fd(), oldState) + defer func() { + restore(r.Fd(), oldState) + fmt.Fprintln(w) + }() } } + if prompt != "" { + fmt.Fprint(w, prompt) + } + // Track total bytes read, not just bytes in the password. This ensures any // errors that might flood the console with nil or -1 bytes infinitely are // capped. var counter int for counter = 0; counter <= maxLength; counter++ { - if v, e := getch(); e != nil { + if v, e := getch(r); e != nil { err = e break } else if v == 127 || v == 8 { if l := len(pass); l > 0 { pass = pass[:l-1] - fmt.Print(string(bs)) + fmt.Fprint(w, string(bs)) } } else if v == 13 || v == 10 { break @@ -66,7 +79,7 @@ func getPasswd(masked bool) ([]byte, error) { break } else if v != 0 { pass = append(pass, v) - fmt.Print(string(mask)) + fmt.Fprint(w, string(mask)) } } @@ -74,18 +87,24 @@ func getPasswd(masked bool) ([]byte, error) { err = ErrMaxLengthExceeded } - fmt.Println() return pass, err } // GetPasswd returns the password read from the terminal without echoing input. // The returned byte array does not include end-of-line characters. func GetPasswd() ([]byte, error) { - return getPasswd(false) + return getPasswd("", false, os.Stdin, os.Stdout) } // GetPasswdMasked returns the password read from the terminal, echoing asterisks. // The returned byte array does not include end-of-line characters. func GetPasswdMasked() ([]byte, error) { - return getPasswd(true) + return getPasswd("", true, os.Stdin, os.Stdout) +} + +// GetPasswdPrompt prompts the user and returns the password read from the terminal. +// If mask is true, then asterisks are echoed. +// The returned byte array does not include end-of-line characters. +func GetPasswdPrompt(prompt string, mask bool, r FdReader, w io.Writer) ([]byte, error) { + return getPasswd(prompt, mask, r, w) }