From 04c4e50d72e1277526df419acfb6c09cd8760233 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Thu, 2 Jul 2020 10:00:18 +0200 Subject: [PATCH] ethapi: don't crash when keystore-specific methods are called but external signer used (#21279) * console: prevent importRawKey from getting into CLI history * internal/ethapi: error on keystore-methods when no keystore is present --- console/console.go | 3 ++- internal/ethapi/api.go | 30 ++++++++++++++++++++++++------ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/console/console.go b/console/console.go index 176db1f960..1dcad3065e 100644 --- a/console/console.go +++ b/console/console.go @@ -39,7 +39,8 @@ import ( ) var ( - passwordRegexp = regexp.MustCompile(`personal.[nus]`) + // u: unlock, s: signXX, sendXX, n: newAccount, i: importXX + passwordRegexp = regexp.MustCompile(`personal.[nusi]`) onlyWhitespace = regexp.MustCompile(`^\s*$`) exit = regexp.MustCompile(`^\s*exit\s*;*\s*$`) ) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 162b38fbe3..99b94bd5c1 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -277,7 +277,11 @@ func (s *PrivateAccountAPI) DeriveAccount(url string, path string, pin *bool) (a // NewAccount will create a new account and returns the address for the new account. func (s *PrivateAccountAPI) NewAccount(password string) (common.Address, error) { - acc, err := fetchKeystore(s.am).NewAccount(password) + ks, err := fetchKeystore(s.am) + if err != nil { + return common.Address{}, err + } + acc, err := ks.NewAccount(password) if err == nil { log.Info("Your new key was generated", "address", acc.Address) log.Warn("Please backup your key file!", "path", acc.URL.Path) @@ -288,8 +292,11 @@ func (s *PrivateAccountAPI) NewAccount(password string) (common.Address, error) } // fetchKeystore retrieves the encrypted keystore from the account manager. -func fetchKeystore(am *accounts.Manager) *keystore.KeyStore { - return am.Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) +func fetchKeystore(am *accounts.Manager) (*keystore.KeyStore, error) { + if ks := am.Backends(keystore.KeyStoreType); len(ks) > 0 { + return ks[0].(*keystore.KeyStore), nil + } + return nil, errors.New("local keystore not used") } // ImportRawKey stores the given hex encoded ECDSA key into the key directory, @@ -299,7 +306,11 @@ func (s *PrivateAccountAPI) ImportRawKey(privkey string, password string) (commo if err != nil { return common.Address{}, err } - acc, err := fetchKeystore(s.am).ImportECDSA(key, password) + ks, err := fetchKeystore(s.am) + if err != nil { + return common.Address{}, err + } + acc, err := ks.ImportECDSA(key, password) return acc.Address, err } @@ -323,7 +334,11 @@ func (s *PrivateAccountAPI) UnlockAccount(ctx context.Context, addr common.Addre } else { d = time.Duration(*duration) * time.Second } - err := fetchKeystore(s.am).TimedUnlock(accounts.Account{Address: addr}, password, d) + ks, err := fetchKeystore(s.am) + if err != nil { + return false, err + } + err = ks.TimedUnlock(accounts.Account{Address: addr}, password, d) if err != nil { log.Warn("Failed account unlock attempt", "address", addr, "err", err) } @@ -332,7 +347,10 @@ func (s *PrivateAccountAPI) UnlockAccount(ctx context.Context, addr common.Addre // LockAccount will lock the account associated with the given address when it's unlocked. func (s *PrivateAccountAPI) LockAccount(addr common.Address) bool { - return fetchKeystore(s.am).Lock(addr) == nil + if ks, err := fetchKeystore(s.am); err == nil { + return ks.Lock(addr) == nil + } + return false } // signTransaction sets defaults and signs the given transaction