github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/client/passphrase_prompt.go (about)

     1  // Copyright 2015 Keybase, Inc. All rights reserved. Use of
     2  // this source code is governed by the included BSD license.
     3  
     4  package client
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"golang.org/x/net/context"
    10  
    11  	"github.com/keybase/client/go/libkb"
    12  	keybase1 "github.com/keybase/client/go/protocol/keybase1"
    13  )
    14  
    15  // promptPassphrase asks the user for a passphrase.
    16  // Used during signup.
    17  func PromptPassphrase(g *libkb.GlobalContext) (keybase1.GetPassphraseRes, error) {
    18  	arg := libkb.DefaultPassphraseArg(libkb.NewMetaContextTODO(g))
    19  	arg.WindowTitle = "Passphrase"
    20  	arg.Prompt = fmt.Sprintf("Pick a strong passphrase (%d+ characters)", libkb.MinPassphraseLength)
    21  	arg.Type = keybase1.PassphraseType_PASS_PHRASE
    22  	return promptPassphraseWithArg(g, arg, "Please reenter your passphrase for confirmation")
    23  }
    24  
    25  // promptNewPassphrase asks the user for a new passphrase.
    26  // Used when changing passphrases.
    27  func PromptNewPassphrase(g *libkb.GlobalContext) (string, error) {
    28  	arg := libkb.DefaultPassphraseArg(libkb.NewMetaContextTODO(g))
    29  	arg.WindowTitle = "Pick a new passphrase"
    30  	arg.Prompt = fmt.Sprintf("Pick a new strong passphrase (%d+ characters)", libkb.MinPassphraseLength)
    31  	arg.Type = keybase1.PassphraseType_VERIFY_PASS_PHRASE
    32  	res, err := promptPassphraseWithArg(g, arg, "Please reenter your new passphrase for confirmation")
    33  	if err != nil {
    34  		return "", err
    35  	}
    36  	return res.Passphrase, nil
    37  }
    38  
    39  // PromptPaperPhrase asks the user to enter a paper key phrase.
    40  // Used in `rekey paper` command.
    41  func PromptPaperPhrase(g *libkb.GlobalContext) (string, error) {
    42  	m := libkb.NewMetaContextTODO(g)
    43  	arg := libkb.DefaultPassphraseArg(m)
    44  	arg.WindowTitle = "Enter a paper key"
    45  	arg.Prompt = "Enter a paper key"
    46  	arg.Type = keybase1.PassphraseType_PAPER_KEY
    47  	arg.Features.ShowTyping.Allow = true
    48  	arg.Features.ShowTyping.DefaultValue = true
    49  
    50  	prompter := newClientPrompter(g)
    51  	res, err := libkb.GetPassphraseUntilCheck(m, arg, prompter, &libkb.PaperChecker{})
    52  	if err != nil {
    53  		return "", err
    54  	}
    55  	return res.Passphrase, nil
    56  }
    57  
    58  func promptPassphraseWithArg(g *libkb.GlobalContext, arg keybase1.GUIEntryArg, promptConfirm string) (keybase1.GetPassphraseRes, error) {
    59  	prompter := newClientPrompter(g)
    60  	m := libkb.NewMetaContextTODO(g)
    61  
    62  	firstPrompt := arg.Prompt
    63  
    64  	for i := 0; i < 10; i++ {
    65  		// get the first passphrase
    66  		res, err := libkb.GetPassphraseUntilCheckWithChecker(m, arg, prompter, &libkb.CheckPassphraseNew)
    67  		if err != nil {
    68  			return keybase1.GetPassphraseRes{}, err
    69  		}
    70  
    71  		// get confirmation passphrase
    72  		arg.RetryLabel = ""
    73  		arg.Prompt = promptConfirm
    74  		confirm, err := libkb.GetPassphraseUntilCheckWithChecker(m, arg, prompter, &libkb.CheckPassphraseNew)
    75  		if err != nil {
    76  			return keybase1.GetPassphraseRes{}, err
    77  		}
    78  
    79  		if res.Passphrase == confirm.Passphrase {
    80  			// success
    81  			return res, nil
    82  		}
    83  
    84  		// setup the prompt, label for new first attempt
    85  		arg.Prompt = firstPrompt
    86  		arg.RetryLabel = "Passphrase mismatch"
    87  	}
    88  
    89  	return keybase1.GetPassphraseRes{}, libkb.RetryExhaustedError{}
    90  }
    91  
    92  type clientPrompter struct {
    93  	libkb.Contextified
    94  }
    95  
    96  var _ libkb.PassphrasePrompter = &clientPrompter{}
    97  
    98  func newClientPrompter(g *libkb.GlobalContext) *clientPrompter {
    99  	return &clientPrompter{Contextified: libkb.NewContextified(g)}
   100  }
   101  
   102  func (c *clientPrompter) Prompt(arg keybase1.GUIEntryArg) (keybase1.GetPassphraseRes, error) {
   103  	cli, err := GetAccountClient(c.G())
   104  	if err != nil {
   105  		return keybase1.GetPassphraseRes{}, err
   106  	}
   107  	promptArg := keybase1.PassphrasePromptArg{
   108  		GuiArg: arg,
   109  	}
   110  	return cli.PassphrasePrompt(context.TODO(), promptArg)
   111  }