Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(client/keys): hide inputting when keys add -i ask for bip39 passphrase #18743

Merged
merged 12 commits into from
Dec 15, 2023
15 changes: 15 additions & 0 deletions client/input/input.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,21 @@ func GetString(prompt string, buf *bufio.Reader) (string, error) {
return strings.TrimSpace(out), nil
}

// GetSecretString returns the secret string output of a given reader.
func GetSecretString(prompt string, buf *bufio.Reader) (secret string, err error) {
if inputIsTty() {
secret, err = speakeasy.FAsk(os.Stderr, prompt)
} else {
secret, err = readLineFromBuf(buf)
}

if err != nil {
return "", err
}

return secret, nil
Halimao marked this conversation as resolved.
Show resolved Hide resolved
}

// inputIsTty returns true iff we have an interactive prompt,
// where we can disable echo and request to repeat the password.
// If false, we can optimize for piped input from another command
Expand Down
11 changes: 8 additions & 3 deletions client/keys/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,16 +313,21 @@ func runAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf

// override bip39 passphrase
if interactive {
bip39Passphrase, err = input.GetString(
bip39Passphrase, err = input.GetSecretString(
"Enter your bip39 passphrase. This is combined with the mnemonic to derive the seed. "+
"Most users should just hit enter to use the default, \"\"", inBuf)
"Most users should just hit enter to use the default, \"\"\n", inBuf)
if err != nil {
return err
}

// if they use one, make them re-enter it
if len(bip39Passphrase) != 0 {
p2, err := input.GetString("Repeat the passphrase:", inBuf)
if len(bip39Passphrase) < input.MinPassLength {
// Return the given passphrase to the upstream client so it can handle a
// non-STDIN failure gracefully.
return fmt.Errorf("passphrase must be at least %d characters", input.MinPassLength)
}
p2, err := input.GetPassword("Repeat the passphrase:\n", inBuf)
if err != nil {
return err
}
Expand Down
14 changes: 13 additions & 1 deletion client/keys/add_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/input"
addresscodec "github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
Expand Down Expand Up @@ -116,7 +117,18 @@ func Test_runAddCmdBasic(t *testing.T) {
fmt.Sprintf("--%s=false", flagRecover),
})

const password = "password1!"
const (
password = "password1!"
invalidPassword = "1234"
)

// set password default interactive key generation successfully
mockIn.Reset("\n\n")
require.NoError(t, cmd.ExecuteContext(ctx))

// set invalid password interactive key generation fail
mockIn.Reset("\n" + invalidPassword + "\n")
require.EqualError(t, cmd.ExecuteContext(ctx), fmt.Sprintf("passphrase must be at least %d characters", input.MinPassLength))

// set password and complete interactive key generation successfully
Halimao marked this conversation as resolved.
Show resolved Hide resolved
mockIn.Reset("\n" + password + "\n" + password + "\n")
Halimao marked this conversation as resolved.
Show resolved Hide resolved
Expand Down