[node.sh] added persist after read from prompt

pull/3219/head
Jacky Wang 4 years ago
parent 89e4c1bf03
commit 992fdfff4b
No known key found for this signature in database
GPG Key ID: 1085CE5F4FF5842C
  1. 49
      cmd/harmony/blsloader/helper.go
  2. 5
      cmd/harmony/blsloader/params.go
  3. 54
      cmd/harmony/blsloader/passProvider.go

@ -1,11 +1,15 @@
package blsloader package blsloader
import ( import (
"bufio"
"fmt" "fmt"
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"syscall"
"golang.org/x/crypto/ssh/terminal"
ffibls "github.com/harmony-one/bls/ffi/go/bls" ffibls "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/internal/blsgen" "github.com/harmony-one/harmony/internal/blsgen"
@ -137,3 +141,48 @@ func isKMSKeyFile(info os.FileInfo) bool {
} }
return true return true
} }
// keyFileToPassFile convert a key file base name to passphrase file base name
func keyFileToPassFile(keyFileBase string) string {
return strings.Trim(keyFileBase, basicKeyExt) + passExt
}
// passFileToKeyFile convert a pass file base name to key file base name
func passFileToKeyFile(passFileBase string) string {
return strings.Trim(passFileBase, passExt) + basicKeyExt
}
func promptGetPassword(prompt string) (string, error) {
if !strings.HasSuffix(prompt, ":") {
prompt += ":"
}
fmt.Print(prompt)
b, err := terminal.ReadPassword(syscall.Stdin)
if err != nil {
return "", err
}
return string(b), nil
}
const yesNoPrompt = "[y/n]: "
func promptYesNo(prompt string) (bool, error) {
if !strings.HasSuffix(prompt, yesNoPrompt) {
prompt = prompt + yesNoPrompt
}
reader := bufio.NewReader(os.Stdin)
for {
fmt.Print(prompt)
response, err := reader.ReadString('\n')
if err != nil {
return false, err
}
response = strings.ToLower(response)
if response == "y" || response == "yes" {
return true, nil
} else if response == "n" || response == "no" {
return false, nil
}
}
}

@ -11,3 +11,8 @@ const (
const ( const (
defPromptTimeout = 1 * time.Second defPromptTimeout = 1 * time.Second
) )
const (
defWritePassDirMode = 0600
defWritePassFileMode = 0600
)

@ -5,10 +5,6 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"syscall"
"golang.org/x/crypto/ssh/terminal"
) )
// passProvider is the interface to provide the passphrase of a bls keys. // passProvider is the interface to provide the passphrase of a bls keys.
@ -23,7 +19,13 @@ type passProvider interface {
} }
// promptPassProvider provides the bls password through console prompt. // promptPassProvider provides the bls password through console prompt.
type promptPassProvider struct{} type promptPassProvider struct {
// if enablePersist is true, after user enter the passphrase, the
// passphrase is also persisted into the persistDir
enablePersist bool
persistDir string
mode int
}
const pwdPromptStr = "Enter passphrase for the BLS key file %s:" const pwdPromptStr = "Enter passphrase for the BLS key file %s:"
@ -31,13 +33,45 @@ func newPromptPassProvider() *promptPassProvider {
return &promptPassProvider{} return &promptPassProvider{}
} }
func (provider *promptPassProvider) setPersist(dirPath string, mode int) *promptPassProvider {
provider.enablePersist = true
os.MkdirAll(dirPath, defWritePassDirMode)
provider.persistDir = dirPath
provider.mode = mode
return provider
}
func (provider *promptPassProvider) getPassphrase(keyFile string) (string, error) { func (provider *promptPassProvider) getPassphrase(keyFile string) (string, error) {
fmt.Printf(pwdPromptStr, keyFile) prompt := fmt.Sprintf(pwdPromptStr, keyFile)
hexBytes, err := terminal.ReadPassword(syscall.Stdin) pass, err := promptGetPassword(prompt)
if err != nil { if err != nil {
return "", err return "", err
} }
return string(hexBytes), nil if provider.enablePersist {
if err := provider.persistPassphrase(keyFile, pass); err != nil {
return "", err
}
}
return pass, nil
}
func (provider *promptPassProvider) persistPassphrase(keyFile string, passPhrase string) error {
passFile := filepath.Join(provider.persistDir, filepath.Base(keyFile))
if _, err := os.Stat(passFile); os.IsNotExist(err) {
// file not exist. Go on create the file
} else if err == nil {
// File exist. Prompt user to overwrite pass file
overwrite, err := promptYesNo(fmt.Sprintf("pass file [%v] already exist. Overwrite? ", passFile))
if err != nil {
return err
}
if !overwrite {
return nil
}
}
return ioutil.WriteFile(passFile, []byte(passPhrase), defWritePassFileMode)
} }
// filePassProvider provide the bls password from the single bls pass file // filePassProvider provide the bls password from the single bls pass file
@ -76,8 +110,8 @@ type dirPassProvider struct {
func (provider *dirPassProvider) getPassphrase(keyFile string) (string, error) { func (provider *dirPassProvider) getPassphrase(keyFile string) (string, error) {
baseName := filepath.Base(keyFile) baseName := filepath.Base(keyFile)
pubKey := strings.TrimSuffix(baseName, basicKeyExt) passKeyBase := keyFileToPassFile(baseName)
passFile := filepath.Join(provider.dirPath, pubKey+passExt) passFile := filepath.Join(provider.dirPath, passKeyBase)
return readPassFromFile(passFile) return readPassFromFile(passFile)
} }

Loading…
Cancel
Save