浏览代码

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)
Guillaume Ballet 6 年之前
父节点
当前提交
7a22da98b9

+ 2 - 2
accounts/scwallet/hub.go

@@ -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
 	}

+ 1 - 0
cmd/geth/main.go

@@ -66,6 +66,7 @@ var (
 		utils.KeyStoreDirFlag,
 		utils.ExternalSignerFlag,
 		utils.NoUSBFlag,
+		utils.SmartCardDaemonPathFlag,
 		utils.DashboardEnabledFlag,
 		utils.DashboardAddrFlag,
 		utils.DashboardPortFlag,

+ 1 - 0
cmd/geth/usage.go

@@ -72,6 +72,7 @@ var AppHelpFlagGroups = []flagGroup{
 			utils.AncientFlag,
 			utils.KeyStoreDirFlag,
 			utils.NoUSBFlag,
+			utils.SmartCardDaemonPathFlag,
 			utils.NetworkIdFlag,
 			utils.TestnetFlag,
 			utils.RinkebyFlag,

+ 27 - 0
cmd/utils/flags.go

@@ -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):

+ 10 - 5
node/config.go

@@ -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)
+			}
 		}
 	}
 

+ 0 - 2
vendor/github.com/gballet/go-libpcsclite/doc.go

@@ -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

+ 35 - 0
vendor/github.com/gballet/go-libpcsclite/doc_bsd.go

@@ -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"

+ 35 - 0
vendor/github.com/gballet/go-libpcsclite/doc_linux.go

@@ -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"

+ 35 - 0
vendor/github.com/gballet/go-libpcsclite/doc_windows.go

@@ -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 = ""

+ 7 - 3
vendor/github.com/gballet/go-libpcsclite/msg.go

@@ -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)
 }

+ 2 - 2
vendor/github.com/gballet/go-libpcsclite/winscard.go

@@ -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
 	}

+ 3 - 3
vendor/vendor.json

@@ -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=",