Allow disabling RPC client TLS for localhost only.
This commit introduces a new flag, --noclienttls, which can be used to disable TLS for the RPC client. However, the flag can only be used when the RPC client is connecting to localhost interfaces. This is intended to prevent accidentally leaking sensitive data when switching between local and remote servers.
This commit is contained in:
parent
469a6f86eb
commit
edaddb0d95
3 changed files with 38 additions and 28 deletions
17
btcwallet.go
17
btcwallet.go
|
@ -90,15 +90,18 @@ func walletMain() error {
|
|||
|
||||
go func() {
|
||||
// Read CA certs and create the RPC client.
|
||||
certs, err := ioutil.ReadFile(cfg.CAFile)
|
||||
if err != nil {
|
||||
log.Warnf("Cannot open CA file: %v", err)
|
||||
// If there's an error reading the CA file, continue
|
||||
// with nil certs and without the client connection
|
||||
certs = nil
|
||||
var certs []byte
|
||||
if !cfg.DisableClientTLS {
|
||||
certs, err = ioutil.ReadFile(cfg.CAFile)
|
||||
if err != nil {
|
||||
log.Warnf("Cannot open CA file: %v", err)
|
||||
// If there's an error reading the CA file, continue
|
||||
// with nil certs and without the client connection
|
||||
certs = nil
|
||||
}
|
||||
}
|
||||
rpcc, err := chain.NewClient(activeNet.Params, cfg.RPCConnect,
|
||||
cfg.BtcdUsername, cfg.BtcdPassword, certs)
|
||||
cfg.BtcdUsername, cfg.BtcdPassword, certs, cfg.DisableClientTLS)
|
||||
if err != nil {
|
||||
log.Errorf("Cannot create chain server RPC client: %v", err)
|
||||
return
|
||||
|
|
|
@ -51,7 +51,7 @@ type Client struct {
|
|||
quitMtx sync.Mutex
|
||||
}
|
||||
|
||||
func NewClient(net *btcnet.Params, connect, user, pass string, certs []byte) (*Client, error) {
|
||||
func NewClient(net *btcnet.Params, connect, user, pass string, certs []byte, disableTLS bool) (*Client, error) {
|
||||
client := Client{
|
||||
netParams: net,
|
||||
enqueueNotification: make(chan interface{}),
|
||||
|
@ -76,6 +76,7 @@ func NewClient(net *btcnet.Params, connect, user, pass string, certs []byte) (*C
|
|||
Pass: pass,
|
||||
Certificates: certs,
|
||||
DisableConnectOnNew: true,
|
||||
DisableTLS: disableTLS,
|
||||
}
|
||||
c, err := btcrpcclient.New(&conf, &ntfnCallbacks)
|
||||
if err != nil {
|
||||
|
|
46
config.go
46
config.go
|
@ -70,6 +70,7 @@ type config struct {
|
|||
RPCMaxClients int64 `long:"rpcmaxclients" description:"Max number of RPC clients for standard connections"`
|
||||
RPCMaxWebsockets int64 `long:"rpcmaxwebsockets" description:"Max number of RPC websocket connections"`
|
||||
DisableServerTLS bool `long:"noservertls" description:"Disable TLS for the RPC server -- NOTE: This is only allowed if the RPC server is bound to localhost"`
|
||||
DisableClientTLS bool `long:"noclienttls" description:"Disable TLS for the RPC client -- NOTE: This is only allowed if the RPC client is connecting to localhost"`
|
||||
MainNet bool `long:"mainnet" description:"Use the main Bitcoin network (default testnet3)"`
|
||||
SimNet bool `long:"simnet" description:"Use the simulation test network (default testnet3)"`
|
||||
KeypoolSize uint `short:"k" long:"keypoolsize" description:"DEPRECATED -- Maximum number of addresses in keypool"`
|
||||
|
@ -371,27 +372,32 @@ func loadConfig() (*config, []string, error) {
|
|||
"127.0.0.1": struct{}{},
|
||||
"::1": struct{}{},
|
||||
}
|
||||
// If CAFile is unset, choose either the copy or local btcd cert.
|
||||
if cfg.CAFile == "" {
|
||||
cfg.CAFile = filepath.Join(cfg.DataDir, defaultCAFilename)
|
||||
RPCHost, _, err := net.SplitHostPort(cfg.RPCConnect)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if cfg.DisableClientTLS {
|
||||
if _, ok := localhostListeners[RPCHost]; !ok {
|
||||
str := "%s: the --noclienttls option may not be used " +
|
||||
"when connecting RPC to non localhost " +
|
||||
"addresses: %s"
|
||||
err := fmt.Errorf(str, funcName, cfg.RPCConnect)
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
fmt.Fprintln(os.Stderr, usageMessage)
|
||||
return nil, nil, err
|
||||
}
|
||||
} else {
|
||||
// If CAFile is unset, choose either the copy or local btcd cert.
|
||||
if cfg.CAFile == "" {
|
||||
cfg.CAFile = filepath.Join(cfg.DataDir, defaultCAFilename)
|
||||
|
||||
// If the CA copy does not exist, check if we're connecting to
|
||||
// a local btcd and switch to its RPC cert if it exists.
|
||||
if !fileExists(cfg.CAFile) {
|
||||
host, _, err := net.SplitHostPort(cfg.RPCConnect)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
switch host {
|
||||
case "localhost":
|
||||
fallthrough
|
||||
|
||||
case "127.0.0.1":
|
||||
fallthrough
|
||||
|
||||
case "::1":
|
||||
if fileExists(btcdHomedirCAFile) {
|
||||
cfg.CAFile = btcdHomedirCAFile
|
||||
// If the CA copy does not exist, check if we're connecting to
|
||||
// a local btcd and switch to its RPC cert if it exists.
|
||||
if !fileExists(cfg.CAFile) {
|
||||
if _, ok := localhostListeners[RPCHost]; ok {
|
||||
if fileExists(btcdHomedirCAFile) {
|
||||
cfg.CAFile = btcdHomedirCAFile
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue