Skip to content

Commit 9b7ffca

Browse files
committed
support clientcert to dcrd
1 parent b1dd23f commit 9b7ffca

File tree

6 files changed

+56
-20
lines changed

6 files changed

+56
-20
lines changed

chainreg/chainregistry.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -300,19 +300,23 @@ func NewPartialChainControl(cfg *Config) (*PartialChainControl, func(), error) {
300300
cfg.ActiveNetParams.RPCPort)
301301
}
302302

303-
dcrdUser := dcrdMode.RPCUser
304-
dcrdPass := dcrdMode.RPCPass
305303
cc.RPCConfig = &rpcclient.ConnConfig{
306304
Host: dcrdHost,
307305
Endpoint: "ws",
308-
User: dcrdUser,
309-
Pass: dcrdPass,
310306
Certificates: rpcCert,
311307
DisableTLS: false,
312308
DisableConnectOnNew: true,
313309
DisableAutoReconnect: false,
314310
}
315-
311+
if dcrdMode.RPCClientCert != "" {
312+
cc.RPCConfig.AuthType = rpcclient.AuthTypeClientCert
313+
cc.RPCConfig.ClientCert = dcrdMode.RPCClientCert
314+
cc.RPCConfig.ClientKey = dcrdMode.RPCClientKey
315+
} else {
316+
cc.RPCConfig.AuthType = rpcclient.AuthTypeBasic
317+
cc.RPCConfig.User = dcrdMode.RPCUser
318+
cc.RPCConfig.Pass = dcrdMode.RPCPass
319+
}
316320
// Verify that the provided dcrd instance exists, is reachable,
317321
// it's on the correct network and has the features required
318322
// for dcrlnd to perform its work.

config.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package dcrlnd
66

77
import (
8+
"crypto/tls"
89
"fmt"
910
"io/ioutil"
1011
"net"
@@ -1468,6 +1469,19 @@ func parseRPCParams(cConfig *lncfg.Chain, nodeConfig interface{},
14681469
var daemonName, confDir, confFile string
14691470
switch conf := nodeConfig.(type) {
14701471
case *lncfg.DcrdConfig:
1472+
// If either RPCClientCert or RPCClientKey are set, assume
1473+
// clientcert auth is wanted.
1474+
if conf.RPCClientCert != "" || conf.RPCClientKey != "" {
1475+
if conf.RPCUser != "" || conf.RPCPass != "" {
1476+
return fmt.Errorf("rpc user and pass may not be used with clientcert")
1477+
}
1478+
if _, err := tls.LoadX509KeyPair(conf.RPCClientCert,
1479+
conf.RPCClientKey); err != nil {
1480+
return fmt.Errorf("failed to load dcrd client keypair: %w", err)
1481+
}
1482+
return nil
1483+
}
1484+
14711485
// If both RPCUser and RPCPass are set, we assume those
14721486
// credentials are good to use.
14731487
if conf.RPCUser != "" && conf.RPCPass != "" {

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ require (
2525
github.com/decred/dcrd/gcs/v4 v4.1.0
2626
github.com/decred/dcrd/hdkeychain/v3 v3.1.2
2727
github.com/decred/dcrd/rpc/jsonrpc/types/v4 v4.3.0
28-
github.com/decred/dcrd/rpcclient/v8 v8.0.1
28+
github.com/decred/dcrd/rpcclient/v8 v8.0.2-0.20251120183434-709b0d251ee0
2929
github.com/decred/dcrd/txscript/v4 v4.1.1
3030
github.com/decred/dcrd/wire v1.7.0
3131
github.com/decred/dcrtest/dcrdtest v1.0.1-0.20240514160637-ade8c37ad1db

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,8 @@ github.com/decred/dcrd/peer/v3 v3.0.2 h1:akcB/L5tZcV/LV5LsiAAeShzvus8mjwvkLI20b1
180180
github.com/decred/dcrd/peer/v3 v3.0.2/go.mod h1:J3Wwi3biKzsIoQS61LnpFyjDgP7oigdoptf2r6yNMBQ=
181181
github.com/decred/dcrd/rpc/jsonrpc/types/v4 v4.3.0 h1:l0DnCcILTNrpy8APF3FLN312ChpkQaAuW30aC/RgBaw=
182182
github.com/decred/dcrd/rpc/jsonrpc/types/v4 v4.3.0/go.mod h1:j+kkRPXPJB5S9VFOsx8SQLcU7PTFkPKRc1aCHN4ENzA=
183-
github.com/decred/dcrd/rpcclient/v8 v8.0.1 h1:hd81e4w1KSqvPcozJlnz6XJfWKDNuahgooH/N5E8vOU=
184-
github.com/decred/dcrd/rpcclient/v8 v8.0.1/go.mod h1:97XD5P/XrZzedePPFPJzc8el2o00q2Kr+Epi4AvRL3o=
183+
github.com/decred/dcrd/rpcclient/v8 v8.0.2-0.20251120183434-709b0d251ee0 h1:baVG2rzOiP1i+oQMD5UH1REYpD/8FA4EpgY65GjAfsI=
184+
github.com/decred/dcrd/rpcclient/v8 v8.0.2-0.20251120183434-709b0d251ee0/go.mod h1:LsWk+nvhFZ1Xb6+TVjPfQObQzLQ16rEp8QoUkToT3rM=
185185
github.com/decred/dcrd/txscript/v4 v4.0.0/go.mod h1:OJtxNc5RqwQyfrRnG2gG8uMeNPo8IAJp+TD1UKXkqk8=
186186
github.com/decred/dcrd/txscript/v4 v4.1.1 h1:R4M2+jMujgQA91899SkL0cW66d6DC76Gx+1W1oEHjc0=
187187
github.com/decred/dcrd/txscript/v4 v4.1.1/go.mod h1:7ybmJoI+b6dxvQ+0aXdZpkyrj0PbnylJCzFxD1g8+/A=

lncfg/dcrd.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package lncfg
22

33
type DcrdConfig struct {
4-
RPCHost string `long:"rpchost" description:"The daemon's rpc listening address. If a port is omitted, then the default port for the selected chain parameters will be used."`
5-
RPCUser string `long:"rpcuser" description:"Username for RPC connections"`
6-
RPCPass string `long:"rpcpass" default-mask:"-" description:"Password for RPC connections"`
7-
RPCCert string `long:"rpccert" description:"File containing the daemon's certificate file"`
8-
RawRPCCert string `long:"rawrpccert" description:"The raw bytes of the daemon's PEM-encoded certificate chain which will be used to authenticate the RPC connection."`
4+
RPCHost string `long:"rpchost" description:"The daemon's rpc listening address. If a port is omitted, then the default port for the selected chain parameters will be used."`
5+
RPCUser string `long:"rpcuser" description:"Username for RPC connections"`
6+
RPCPass string `long:"rpcpass" default-mask:"-" description:"Password for RPC connections"`
7+
RPCCert string `long:"rpccert" description:"File containing the daemon's certificate file"`
8+
RawRPCCert string `long:"rawrpccert" description:"The raw bytes of the daemon's PEM-encoded certificate chain which will be used to authenticate the RPC connection."`
9+
RPCClientCert string `long:"rpcclientcert" description:"TLS client certificate to present to authenticate RPC connections to dcrd"`
10+
RPCClientKey string `long:"rpcclientkey" description:"Key for dcrd RPC client certificate"`
911
}

lnwallet/dcrwallet/rpcsync.go

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ package dcrwallet
22

33
import (
44
"context"
5+
"os"
56
"sync"
67
"time"
78

8-
"github.com/decred/dcrd/chaincfg/v3"
9-
"github.com/decred/dcrd/rpcclient/v8"
10-
119
"decred.org/dcrwallet/v4/chain"
1210
"decred.org/dcrwallet/v4/errors"
11+
"github.com/decred/dcrd/chaincfg/v3"
12+
"github.com/decred/dcrd/rpcclient/v8"
1313
)
1414

1515
// RPCSyncer implements the required methods for synchronizing a DcrWallet
@@ -38,12 +38,28 @@ func NewRPCSyncer(rpcConfig rpcclient.ConnConfig, net *chaincfg.Params) (*RPCSyn
3838

3939
// start the syncer backend and begin synchronizing the given wallet.
4040
func (s *RPCSyncer) start(w *DcrWallet) error {
41+
var clientCert, clientKey []byte
42+
var err error
4143

44+
if s.rpcConfig.ClientCert != "" {
45+
clientCert, err = os.ReadFile(s.rpcConfig.ClientCert)
46+
if err != nil && !os.IsNotExist(err) {
47+
return err
48+
}
49+
}
50+
if s.rpcConfig.ClientKey != "" {
51+
clientKey, err = os.ReadFile(s.rpcConfig.ClientKey)
52+
if err != nil && !os.IsNotExist(err) {
53+
return err
54+
}
55+
}
4256
chainRpcOpts := chain.RPCOptions{
43-
Address: s.rpcConfig.Host,
44-
User: s.rpcConfig.User,
45-
Pass: s.rpcConfig.Pass,
46-
CA: s.rpcConfig.Certificates,
57+
Address: s.rpcConfig.Host,
58+
User: s.rpcConfig.User,
59+
Pass: s.rpcConfig.Pass,
60+
CA: s.rpcConfig.Certificates,
61+
ClientCert: clientCert,
62+
ClientKey: clientKey,
4763
}
4864

4965
disableDiscoverAccts, err := w.cfg.DB.AccountDiscoveryDisabled()

0 commit comments

Comments
 (0)