diff --git a/cmd/clef/main.go b/cmd/clef/main.go index ad7ba186d..0ea6f36f1 100644 --- a/cmd/clef/main.go +++ b/cmd/clef/main.go @@ -194,6 +194,7 @@ func init() { chainIdFlag, utils.LightKDFFlag, utils.NoUSBFlag, + utils.SmartCardDaemonPathFlag, utils.RPCListenAddrFlag, utils.RPCVirtualHostsFlag, utils.IPCDisabledFlag, @@ -419,10 +420,11 @@ func signer(c *cli.Context) error { lightKdf = c.GlobalBool(utils.LightKDFFlag.Name) advanced = c.GlobalBool(advancedMode.Name) nousb = c.GlobalBool(utils.NoUSBFlag.Name) + scpath = c.GlobalString(utils.SmartCardDaemonPathFlag.Name) ) log.Info("Starting signer", "chainid", chainId, "keystore", ksLoc, "light-kdf", lightKdf, "advanced", advanced) - am := core.StartClefAccountManager(ksLoc, nousb, lightKdf) + am := core.StartClefAccountManager(ksLoc, nousb, lightKdf, scpath) apiImpl := core.NewSignerAPI(am, chainId, nousb, ui, db, advanced, pwStorage) // Establish the bidirectional communication, by creating a new UI backend and registering diff --git a/signer/core/api.go b/signer/core/api.go index 9798ff2b5..251ee55dc 100644 --- a/signer/core/api.go +++ b/signer/core/api.go @@ -22,11 +22,13 @@ import ( "errors" "fmt" "math/big" + "os" "reflect" "strings" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/accounts/scwallet" "github.com/ethereum/go-ethereum/accounts/usbwallet" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -124,7 +126,7 @@ type Metadata struct { Origin string `json:"Origin"` } -func StartClefAccountManager(ksLocation string, nousb, lightKDF bool) *accounts.Manager { +func StartClefAccountManager(ksLocation string, nousb, lightKDF bool, scpath string) *accounts.Manager { var ( backends []accounts.Backend n, p = keystore.StandardScryptN, keystore.StandardScryptP @@ -159,6 +161,26 @@ func StartClefAccountManager(ksLocation string, nousb, lightKDF bool) *accounts. log.Debug("Trezor support enabled via WebUSB") } } + + // Start a smart card hub + if len(scpath) > 0 { + // Sanity check that the smartcard path is valid + fi, err := os.Stat(scpath) + if err != nil { + log.Info("Smartcard socket file missing, disabling", "err", err) + } else { + if fi.Mode()&os.ModeType != os.ModeSocket { + log.Error("Invalid smartcard socket file type", "path", scpath, "type", fi.Mode().String()) + } else { + if schub, err := scwallet.NewHub(scpath, scwallet.Scheme, ksLocation); err != nil { + log.Warn(fmt.Sprintf("Failed to start smart card hub, disabling: %v", err)) + } else { + backends = append(backends, schub) + } + } + } + } + // Clef doesn't allow insecure http account unlock. return accounts.NewManager(&accounts.Config{InsecureUnlockAllowed: false}, backends...) } diff --git a/signer/core/api_test.go b/signer/core/api_test.go index b458aa03e..1eba20ef4 100644 --- a/signer/core/api_test.go +++ b/signer/core/api_test.go @@ -125,7 +125,7 @@ func setup(t *testing.T) (*core.SignerAPI, *headlessUi) { t.Fatal(err.Error()) } ui := &headlessUi{make(chan string, 20), make(chan string, 20)} - am := core.StartClefAccountManager(tmpDirName(t), true, true) + am := core.StartClefAccountManager(tmpDirName(t), true, true, "") api := core.NewSignerAPI(am, 1337, true, ui, db, true, &storage.NoStorage{}) return api, ui