// Package ask implements interactive password retrieval package ask import ( "errors" "io" "os" "golang.org/x/crypto/ssh/terminal" ) var ( ErrNoPassword = errors.New("please provide a password") ErrNoMatch = errors.New("passwords don't match") ) // Confirmed asks for password twice func Confirmed() (string, error) { restore, err := makeRaw(os.Stdin) if err != nil { return "", err } defer restore() pass, err := ask(os.Stdin, "passphrase: ") if err != nil { return "", err } pass2, err := ask(os.Stdin, "confirm passphrase: ") if err != nil { return "", err } if pass != pass2 { return "", ErrNoMatch } return pass, nil } // Password ask for password once func Password() (string, error) { restore, err := makeRaw(os.Stdin) if err != nil { return "", err } defer restore() return ask(os.Stdin, "passphrase: ") } func ask(rw io.ReadWriter, prompt string) (string, error) { pass, err := terminal.NewTerminal(rw, "").ReadPassword(prompt) if err != nil { return "", err } if len(pass) == 0 { return "", ErrNoPassword } return pass, nil } func makeRaw(f *os.File) (func(), error) { fd := int(f.Fd()) oldState, err := terminal.MakeRaw(fd) if err != nil { return nil, err } return func() { terminal.Restore(fd, oldState) }, nil }