mirror of https://github.com/status-im/op-geth.git
accounts/scwallet: flag to specify path to smartcard daemon (#19439)
* accounts/scwallet: Add a switch to enable smartcard support * accounts: change the meaning of the switch * disable card support in windows until tested * only activate account if pcscd socket file is present * the switch is now the path to the socket file * accounts/scwallet: holiman's review feedback * accounts/scwallet: send the path to go-pcsclite * accounts/scwallet: add default, per platform path * accounts/scwallet: fix error log warning * accounts/scwallet: update pcsc lib to latest * accounts/scwallet: use default path from pcsclite * scwallet: forgot to change switch name * cmd: minor style cleanups (error handling first, then happy path)
This commit is contained in:
parent
30263ad37d
commit
7a22da98b9
|
@ -152,8 +152,8 @@ func (hub *Hub) setPairing(wallet *Wallet, pairing *smartcardPairing) error {
|
|||
}
|
||||
|
||||
// NewHub creates a new hardware wallet manager for smartcards.
|
||||
func NewHub(scheme string, datadir string) (*Hub, error) {
|
||||
context, err := pcsc.EstablishContext(pcsc.ScopeSystem)
|
||||
func NewHub(daemonPath string, scheme string, datadir string) (*Hub, error) {
|
||||
context, err := pcsc.EstablishContext(daemonPath, pcsc.ScopeSystem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -66,6 +66,7 @@ var (
|
|||
utils.KeyStoreDirFlag,
|
||||
utils.ExternalSignerFlag,
|
||||
utils.NoUSBFlag,
|
||||
utils.SmartCardDaemonPathFlag,
|
||||
utils.DashboardEnabledFlag,
|
||||
utils.DashboardAddrFlag,
|
||||
utils.DashboardPortFlag,
|
||||
|
|
|
@ -72,6 +72,7 @@ var AppHelpFlagGroups = []flagGroup{
|
|||
utils.AncientFlag,
|
||||
utils.KeyStoreDirFlag,
|
||||
utils.NoUSBFlag,
|
||||
utils.SmartCardDaemonPathFlag,
|
||||
utils.NetworkIdFlag,
|
||||
utils.TestnetFlag,
|
||||
utils.RinkebyFlag,
|
||||
|
|
|
@ -58,6 +58,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/p2p/netutil"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
whisper "github.com/ethereum/go-ethereum/whisper/whisperv6"
|
||||
pcsclite "github.com/gballet/go-libpcsclite"
|
||||
cli "gopkg.in/urfave/cli.v1"
|
||||
)
|
||||
|
||||
|
@ -129,6 +130,11 @@ var (
|
|||
Name: "nousb",
|
||||
Usage: "Disables monitoring for and managing USB hardware wallets",
|
||||
}
|
||||
SmartCardDaemonPathFlag = cli.StringFlag{
|
||||
Name: "pcscdpath",
|
||||
Usage: "Path to the smartcard daemon (pcscd) socket file",
|
||||
Value: pcsclite.PCSCDSockName,
|
||||
}
|
||||
NetworkIdFlag = cli.Uint64Flag{
|
||||
Name: "networkid",
|
||||
Usage: "Network identifier (integer, 1=Frontier, 2=Morden (disused), 3=Ropsten, 4=Rinkeby)",
|
||||
|
@ -1126,6 +1132,7 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) {
|
|||
setWS(ctx, cfg)
|
||||
setNodeUserIdent(ctx, cfg)
|
||||
setDataDir(ctx, cfg)
|
||||
setSmartCard(ctx, cfg)
|
||||
|
||||
if ctx.GlobalIsSet(ExternalSignerFlag.Name) {
|
||||
cfg.ExternalSigner = ctx.GlobalString(ExternalSignerFlag.Name)
|
||||
|
@ -1145,6 +1152,26 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) {
|
|||
}
|
||||
}
|
||||
|
||||
func setSmartCard(ctx *cli.Context, cfg *node.Config) {
|
||||
// Skip enabling smartcards if no path is set
|
||||
path := ctx.GlobalString(SmartCardDaemonPathFlag.Name)
|
||||
if path == "" {
|
||||
return
|
||||
}
|
||||
// Sanity check that the smartcard path is valid
|
||||
fi, err := os.Stat(path)
|
||||
if err != nil {
|
||||
log.Error("Failed to verify smartcard daemon path", "path", path, "err", err)
|
||||
return
|
||||
}
|
||||
if fi.Mode()&os.ModeType != os.ModeSocket {
|
||||
log.Error("Invalid smartcard daemon path", "path", path, "type", fi.Mode().String())
|
||||
return
|
||||
}
|
||||
// Smartcard daemon path exists and is a socket, enable it
|
||||
cfg.SmartCardDaemonPath = path
|
||||
}
|
||||
|
||||
func setDataDir(ctx *cli.Context, cfg *node.Config) {
|
||||
switch {
|
||||
case ctx.GlobalIsSet(DataDirFlag.Name):
|
||||
|
|
|
@ -95,6 +95,9 @@ type Config struct {
|
|||
// NoUSB disables hardware wallet monitoring and connectivity.
|
||||
NoUSB bool `toml:",omitempty"`
|
||||
|
||||
// SmartCardDaemonPath is the path to the smartcard daemon's socket
|
||||
SmartCardDaemonPath string `toml:",omitempty"`
|
||||
|
||||
// IPCPath is the requested location to place the IPC endpoint. If the path is
|
||||
// a simple file name, it is placed inside the data directory (or on the root
|
||||
// pipe path on Windows), whereas if it's a resolvable path name (absolute or
|
||||
|
@ -505,11 +508,13 @@ func makeAccountManager(conf *Config) (*accounts.Manager, string, error) {
|
|||
backends = append(backends, trezorhub)
|
||||
}
|
||||
}
|
||||
// Start a smart card hub
|
||||
if schub, err := scwallet.NewHub(scwallet.Scheme, keydir); err != nil {
|
||||
log.Warn(fmt.Sprintf("Failed to start smart card hub, disabling: %v", err))
|
||||
} else {
|
||||
backends = append(backends, schub)
|
||||
if len(conf.SmartCardDaemonPath) > 0 {
|
||||
// Start a smart card hub
|
||||
if schub, err := scwallet.NewHub(conf.SmartCardDaemonPath, scwallet.Scheme, keydir); err != nil {
|
||||
log.Warn(fmt.Sprintf("Failed to start smart card hub, disabling: %v", err))
|
||||
} else {
|
||||
backends = append(backends, schub)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,8 +61,6 @@ const (
|
|||
SCardPowever = 0x0010 /* Card is powered */
|
||||
SCardNegotiable = 0x0020 /* Ready for PTS */
|
||||
SCardSpecific = 0x0040 /* PTS has been set */
|
||||
|
||||
PCSCDSockName = "/run/pcscd/pcscd.comm"
|
||||
)
|
||||
|
||||
// List of commands to send to the daemon
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
// BSD 3-Clause License
|
||||
//
|
||||
// Copyright (c) 2019, Guillaume Ballet
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// +build dragonfly darwin freebsd netbsd openbsd solaris
|
||||
|
||||
package pcsc
|
||||
|
||||
const PCSCDSockName string = "/var/run/pcscd/pcscd.comm"
|
|
@ -0,0 +1,35 @@
|
|||
// BSD 3-Clause License
|
||||
//
|
||||
// Copyright (c) 2019, Guillaume Ballet
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// +build linux
|
||||
|
||||
package pcsc
|
||||
|
||||
const PCSCDSockName string = "/run/pcscd/pcscd.comm"
|
|
@ -0,0 +1,35 @@
|
|||
// BSD 3-Clause License
|
||||
//
|
||||
// Copyright (c) 2019, Guillaume Ballet
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// +build windows
|
||||
|
||||
package pcsc
|
||||
|
||||
const PCSCDSockName string = ""
|
|
@ -62,7 +62,7 @@ func messageSendWithHeader(command uint32, conn net.Conn, data []byte) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// ClientSetupSession prepares a communication channel for the client to talk to the server.
|
||||
// clientSetupSession prepares a communication channel for the client to talk to the server.
|
||||
// This is called by the application to create a socket for local IPC with the
|
||||
// server. The socket is associated to the file \c PCSCLITE_CSOCK_NAME.
|
||||
/*
|
||||
|
@ -73,6 +73,10 @@ func messageSendWithHeader(command uint32, conn net.Conn, data []byte) error {
|
|||
* @retval -1 The socket can not open a connection.
|
||||
* @retval -1 Can not set the socket to non-blocking.
|
||||
*/
|
||||
func clientSetupSession() (net.Conn, error) {
|
||||
return net.Dial("unix", PCSCDSockName)
|
||||
func clientSetupSession(daemonPath string) (net.Conn, error) {
|
||||
path := PCSCDSockName
|
||||
if len(daemonPath) > 0 {
|
||||
path = daemonPath
|
||||
}
|
||||
return net.Dial("unix", path)
|
||||
}
|
||||
|
|
|
@ -56,10 +56,10 @@ type Client struct {
|
|||
// EstablishContext asks the PCSC daemon to create a context
|
||||
// handle for further communication with connected cards and
|
||||
// readers.
|
||||
func EstablishContext(scope uint32) (*Client, error) {
|
||||
func EstablishContext(path string, scope uint32) (*Client, error) {
|
||||
client := &Client{}
|
||||
|
||||
conn, err := clientSetupSession()
|
||||
conn, err := clientSetupSession(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -135,10 +135,10 @@
|
|||
"revisionTime": "2018-04-18T12:24:29Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "GXqHzd0XkPLX/iulpOncaxbxzZo=",
|
||||
"checksumSHA1": "+fiJGimxPPRSfi9sED4Lp6ytBeo=",
|
||||
"path": "github.com/gballet/go-libpcsclite",
|
||||
"revision": "312b5175032f98274685a4dd81935a92ad2412a5",
|
||||
"revisionTime": "2019-04-03T18:15:18Z"
|
||||
"revision": "2fd9b619dd3c5d74acbd975f997a6441984d74a7",
|
||||
"revisionTime": "2019-05-28T10:50:17Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "gxV/cPPLkByTdY8y172t7v4qcZA=",
|
||||
|
|
Loading…
Reference in New Issue