Skip to content

Commit

Permalink
Create limited RPC user.
Browse files Browse the repository at this point in the history
The limited user is specified with the --rpclimituser and
--rpclimitpass options (or the equivalent in the config file).
The config struct and loadConfig() are updated to take the
new options into account. The limited user can have neither
the same username nor the same password as the admin user.

The package-level rpcLimit map in rpcserver.go specifies
the RPC commands accessible by limited users. This map
includes both HTTP/S and websocket commands.

The checkAuth function gets a new return parameter to
signify whether the user is authorized to change server
state. The result is passed to the jsonRPCRead function and
to the WebsocketHandler function in rpcwebsocket.go.

The wsClient struct is updated with an "isAdmin" field
signifying that the client is authorized to change server
state, written by WebsocketHandler and handleMessage.
The handleMessage function also checks the field to
allow or disallow an RPC call.

The following documentation files are updated:
- doc.go
- sample-btcd.conf
- docs/README.md
- docs/json_rpc_api.md
- docs/configure_rpc_server_listen_interfaces.md
  • Loading branch information
aakselrod committed Apr 13, 2015
1 parent abe74f1 commit 4a1445a
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 82 deletions.
27 changes: 25 additions & 2 deletions config.go
Expand Up @@ -77,12 +77,14 @@ type config struct {
BanDuration time.Duration `long:"banduration" description:"How long to ban misbehaving peers. Valid time units are {s, m, h}. Minimum 1 second"` BanDuration time.Duration `long:"banduration" description:"How long to ban misbehaving peers. Valid time units are {s, m, h}. Minimum 1 second"`
RPCUser string `short:"u" long:"rpcuser" description:"Username for RPC connections"` RPCUser string `short:"u" long:"rpcuser" description:"Username for RPC connections"`
RPCPass string `short:"P" long:"rpcpass" default-mask:"-" description:"Password for RPC connections"` RPCPass string `short:"P" long:"rpcpass" default-mask:"-" description:"Password for RPC connections"`
RPCLimitUser string `long:"rpclimituser" description:"Username for limited RPC connections"`
RPCLimitPass string `long:"rpclimitpass" default-mask:"-" description:"Password for limited RPC connections"`
RPCListeners []string `long:"rpclisten" description:"Add an interface/port to listen for RPC connections (default port: 8334, testnet: 18334)"` RPCListeners []string `long:"rpclisten" description:"Add an interface/port to listen for RPC connections (default port: 8334, testnet: 18334)"`
RPCCert string `long:"rpccert" description:"File containing the certificate file"` RPCCert string `long:"rpccert" description:"File containing the certificate file"`
RPCKey string `long:"rpckey" description:"File containing the certificate key"` RPCKey string `long:"rpckey" description:"File containing the certificate key"`
RPCMaxClients int `long:"rpcmaxclients" description:"Max number of RPC clients for standard connections"` RPCMaxClients int `long:"rpcmaxclients" description:"Max number of RPC clients for standard connections"`
RPCMaxWebsockets int `long:"rpcmaxwebsockets" description:"Max number of RPC websocket connections"` RPCMaxWebsockets int `long:"rpcmaxwebsockets" description:"Max number of RPC websocket connections"`
DisableRPC bool `long:"norpc" description:"Disable built-in RPC server -- NOTE: The RPC server is disabled by default if no rpcuser/rpcpass is specified"` DisableRPC bool `long:"norpc" description:"Disable built-in RPC server -- NOTE: The RPC server is disabled by default if no rpcuser/rpcpass or rpclimituser/rpclimitpass is specified"`
DisableTLS bool `long:"notls" description:"Disable TLS for the RPC server -- NOTE: This is only allowed if the RPC server is bound to localhost"` DisableTLS bool `long:"notls" description:"Disable TLS for the RPC server -- NOTE: This is only allowed if the RPC server is bound to localhost"`
DisableDNSSeed bool `long:"nodnsseed" description:"Disable DNS seeding for peers"` DisableDNSSeed bool `long:"nodnsseed" description:"Disable DNS seeding for peers"`
ExternalIPs []string `long:"externalip" description:"Add an ip to the list of local addresses we claim to listen on to peers"` ExternalIPs []string `long:"externalip" description:"Add an ip to the list of local addresses we claim to listen on to peers"`
Expand Down Expand Up @@ -546,8 +548,29 @@ func loadConfig() (*config, []string, error) {
} }
} }


// Check to make sure limited and admin users don't have the same username
if cfg.RPCUser == cfg.RPCLimitUser && cfg.RPCUser != "" {
str := "%s: --rpcuser and --rpclimituser must not specify the " +
"same username"
err := fmt.Errorf(str, funcName)
fmt.Fprintln(os.Stderr, err)
fmt.Fprintln(os.Stderr, usageMessage)
return nil, nil, err
}

// Check to make sure limited and admin users don't have the same password
if cfg.RPCPass == cfg.RPCLimitPass && cfg.RPCPass != "" {
str := "%s: --rpcpass and --rpclimitpass must not specify the " +
"same password"
err := fmt.Errorf(str, funcName)
fmt.Fprintln(os.Stderr, err)
fmt.Fprintln(os.Stderr, usageMessage)
return nil, nil, err
}

// The RPC server is disabled if no username or password is provided. // The RPC server is disabled if no username or password is provided.
if cfg.RPCUser == "" || cfg.RPCPass == "" { if (cfg.RPCUser == "" || cfg.RPCPass == "") &&
(cfg.RPCLimitUser == "" || cfg.RPCLimitPass == "") {
cfg.DisableRPC = true cfg.DisableRPC = true
} }


Expand Down
2 changes: 2 additions & 0 deletions doc.go
Expand Up @@ -37,6 +37,8 @@ Application Options:
are {s, m, h}. Minimum 1 second (24h0m0s) are {s, m, h}. Minimum 1 second (24h0m0s)
-u, --rpcuser= Username for RPC connections -u, --rpcuser= Username for RPC connections
-P, --rpcpass= Password for RPC connections -P, --rpcpass= Password for RPC connections
--rpclimituser= Username for limited RPC connections
--rpclimitpass= Password for limited RPC connections
--rpclisten= Add an interface/port to listen for RPC connections --rpclisten= Add an interface/port to listen for RPC connections
(default port: 8334, testnet: 18334) (default port: 8334, testnet: 18334)
--rpccert= File containing the certificate file --rpccert= File containing the certificate file
Expand Down
13 changes: 11 additions & 2 deletions docs/README.md
Expand Up @@ -89,26 +89,35 @@ options, which can be viewed by running: `$ btcd --help`.
btcctl is a command line utility that can be used to both control and query btcd btcctl is a command line utility that can be used to both control and query btcd
via [RPC](http://www.wikipedia.org/wiki/Remote_procedure_call). btcd does via [RPC](http://www.wikipedia.org/wiki/Remote_procedure_call). btcd does
**not** enable its RPC server by default; You must configure at minimum both an **not** enable its RPC server by default; You must configure at minimum both an
RPC username and password: RPC username and password or both an RPC limited username and password:


* btcd.conf configuration file * btcd.conf configuration file
``` ```
[Application Options] [Application Options]
rpcuser=myuser rpcuser=myuser
rpcpass=SomeDecentp4ssw0rd rpcpass=SomeDecentp4ssw0rd
rpclimituser=mylimituser
rpclimitpass=Limitedp4ssw0rd
``` ```
* btcctl.conf configuration file * btcctl.conf configuration file
``` ```
[Application Options] [Application Options]
rpcuser=myuser rpcuser=myuser
rpcpass=SomeDecentp4ssw0rd rpcpass=SomeDecentp4ssw0rd
``` ```
OR
```
[Application Options]
rpcuser=mylimituser
rpcpass=Limitedp4ssw0rd
```
For a list of available options, run: `$ btcctl --help` For a list of available options, run: `$ btcctl --help`


<a name="Mining" /> <a name="Mining" />
**2.4 Mining**<br /> **2.4 Mining**<br />
btcd supports both the `getwork` and `getblocktemplate` RPCs although the btcd supports both the `getwork` and `getblocktemplate` RPCs although the
`getwork` RPC is deprecated and will likely be removed in a future release.<br /> `getwork` RPC is deprecated and will likely be removed in a future release.
The limited user cannot access these RPCs.<br />


**1. Add the payment addresses with the `miningaddr` option.**<br /> **1. Add the payment addresses with the `miningaddr` option.**<br />


Expand Down
9 changes: 5 additions & 4 deletions docs/configure_rpc_server_listen_interfaces.md
Expand Up @@ -7,10 +7,11 @@ options). The configuration file takes one entry per line.
A few things to note regarding the RPC server: A few things to note regarding the RPC server:
* The RPC server will **not** be enabled unless the `rpcuser` and `rpcpass` * The RPC server will **not** be enabled unless the `rpcuser` and `rpcpass`
options are specified. options are specified.
* When the `rpcuser` and `rpcpass` options are specified, the RPC server will * When the `rpcuser` and `rpcpass` and/or `rpclimituser` and `rpclimitpass`
only listen on localhost IPv4 and IPv6 interfaces by default. You will need options are specified, the RPC server will only listen on localhost IPv4 and
to override the RPC listen interfaces to include external interfaces if you IPv6 interfaces by default. You will need to override the RPC listen
want to connect from a remote machine. interfaces to include external interfaces if you want to connect from a remote
machine.
* The RPC server has TLS enabled by default, even for localhost. You may use * The RPC server has TLS enabled by default, even for localhost. You may use
the `--notls` option to disable it, but only when all listeners are on the `--notls` option to disable it, but only when all listeners are on
localhost interfaces. localhost interfaces.
Expand Down
88 changes: 46 additions & 42 deletions docs/json_rpc_api.md
Expand Up @@ -89,16 +89,19 @@ JSON-RPC API are:
The following authentication details are needed before establishing a connection The following authentication details are needed before establishing a connection
to a btcd RPC server: to a btcd RPC server:


* **rpcuser** is the username that the btcd RPC server is configured with * **rpcuser** is the full-access username configured for the btcd RPC server
* **rpcpass** is the password that the btcd RPC server is configured with * **rpcpass** is the full-access password configured for the btcd RPC server
* **rpclimituser** is the limited username configured for the btcd RPC server
* **rpclimitpass** is the limited password configured for the btcd RPC server
* **rpccert** is the PEM-encoded X.509 certificate (public key) that the btcd * **rpccert** is the PEM-encoded X.509 certificate (public key) that the btcd
server is configured with. It is automatically generated by btcd and placed server is configured with. It is automatically generated by btcd and placed
in the btcd home directory (which is typically `%LOCALAPPDATA%\Btcd` on in the btcd home directory (which is typically `%LOCALAPPDATA%\Btcd` on
Windows and `~/.btcd` on POSIX-like OSes) Windows and `~/.btcd` on POSIX-like OSes)


**NOTE:** As mentioned above, btcd is secure by default which means the RPC **NOTE:** As mentioned above, btcd is secure by default which means the RPC
server is not running unless configured with a **rpcuser** and **rpcpass** and server is not running unless configured with a **rpcuser** and **rpcpass**
uses TLS authentication for all connections. and/or a **rpclimituser** and **rpclimitpass**, and uses TLS authentication for
all connections.


Depending on which connection transaction you are using, you can choose one of Depending on which connection transaction you are using, you can choose one of
two, mutually exclusive, methods. two, mutually exclusive, methods.
Expand Down Expand Up @@ -143,37 +146,37 @@ API compatible with the original bitcoind/bitcoin-qt client.
The following is an overview of the RPC methods and their current status. Click The following is an overview of the RPC methods and their current status. Click
the method name for further details such as parameter and return information. the method name for further details such as parameter and return information.


|#|Method|Description| |#|Method|Safe for limited user?|Description|
|---|------|-----------| |---|------|----------|-----------|
|1|[addnode](#addnode)|Attempts to add or remove a persistent peer.| |1|[addnode](#addnode)|N|Attempts to add or remove a persistent peer.|
|2|[createrawtransaction](#createrawtransaction)|Returns a new transaction spending the provided inputs and sending to the provided addresses.| |2|[createrawtransaction](#createrawtransaction)|Y|Returns a new transaction spending the provided inputs and sending to the provided addresses.|
|3|[decoderawtransaction](#decoderawtransaction)|Returns a JSON object representing the provided serialized, hex-encoded transaction.| |3|[decoderawtransaction](#decoderawtransaction)|Y|Returns a JSON object representing the provided serialized, hex-encoded transaction.|
|4|[decodescript](#decodescript)|Returns a JSON object with information about the provided hex-encoded script.| |4|[decodescript](#decodescript)|Y|Returns a JSON object with information about the provided hex-encoded script.|
|5|[getaddednodeinfo](#getaddednodeinfo)|Returns information about manually added (persistent) peers.| |5|[getaddednodeinfo](#getaddednodeinfo)|N|Returns information about manually added (persistent) peers.|
|6|[getbestblockhash](#getbestblockhash)|Returns the hash of the of the best (most recent) block in the longest block chain.| |6|[getbestblockhash](#getbestblockhash)|Y|Returns the hash of the of the best (most recent) block in the longest block chain.|
|7|[getblock](#getblock)|Returns information about a block given its hash.| |7|[getblock](#getblock)|Y|Returns information about a block given its hash.|
|8|[getblockcount](#getblockcount)|Returns the number of blocks in the longest block chain.| |8|[getblockcount](#getblockcount)|Y|Returns the number of blocks in the longest block chain.|
|9|[getblockhash](#getblockhash)|Returns hash of the block in best block chain at the given height.| |9|[getblockhash](#getblockhash)|Y|Returns hash of the block in best block chain at the given height.|
|10|[getconnectioncount](#getconnectioncount)|Returns the number of active connections to other peers.| |10|[getconnectioncount](#getconnectioncount)|N|Returns the number of active connections to other peers.|
|11|[getdifficulty](#getdifficulty)|Returns the proof-of-work difficulty as a multiple of the minimum difficulty.| |11|[getdifficulty](#getdifficulty)|Y|Returns the proof-of-work difficulty as a multiple of the minimum difficulty.|
|12|[getgenerate](#getgenerate)|Return if the server is set to generate coins (mine) or not.| |12|[getgenerate](#getgenerate)|N|Return if the server is set to generate coins (mine) or not.|
|13|[gethashespersec](#gethashespersec)|Returns a recent hashes per second performance measurement while generating coins (mining).| |13|[gethashespersec](#gethashespersec)|N|Returns a recent hashes per second performance measurement while generating coins (mining).|
|14|[getinfo](#getinfo)|Returns a JSON object containing various state info.| |14|[getinfo](#getinfo)|Y|Returns a JSON object containing various state info.|
|15|[getmininginfo](#getmininginfo)|Returns a JSON object containing mining-related information.| |15|[getmininginfo](#getmininginfo)|N|Returns a JSON object containing mining-related information.|
|16|[getnettotals](#getnettotals)|Returns a JSON object containing network traffic statistics.| |16|[getnettotals](#getnettotals)|Y|Returns a JSON object containing network traffic statistics.|
|17|[getnetworkhashps](#getnetworkhashps)|Returns the estimated network hashes per second for the block heights provided by the parameters.| |17|[getnetworkhashps](#getnetworkhashps)|Y|Returns the estimated network hashes per second for the block heights provided by the parameters.|
|18|[getpeerinfo](#getpeerinfo)|Returns information about each connected network peer as an array of json objects.| |18|[getpeerinfo](#getpeerinfo)|N|Returns information about each connected network peer as an array of json objects.|
|19|[getrawmempool](#getrawmempool)|Returns an array of hashes for all of the transactions currently in the memory pool.| |19|[getrawmempool](#getrawmempool)|Y|Returns an array of hashes for all of the transactions currently in the memory pool.|
|20|[getrawtransaction](#getrawtransaction)|Returns information about a transaction given its hash.| |20|[getrawtransaction](#getrawtransaction)|Y|Returns information about a transaction given its hash.|
|21|[getwork](#getwork)|Returns formatted hash data to work on or checks and submits solved data.<br /><font color="orange">NOTE: Since btcd does not have the wallet integrated to provide payment addresses, btcd must be configured via the `--miningaddr` option to provide which payment addresses to pay created blocks to for this RPC to function.</font>| |21|[getwork](#getwork)|N|Returns formatted hash data to work on or checks and submits solved data.<br /><font color="orange">NOTE: Since btcd does not have the wallet integrated to provide payment addresses, btcd must be configured via the `--miningaddr` option to provide which payment addresses to pay created blocks to for this RPC to function.</font>|
|22|[help](#help)|Returns a list of all commands or help for a specified command.| |22|[help](#help)|Y|Returns a list of all commands or help for a specified command.|
|23|[ping](#ping)|Queues a ping to be sent to each connected peer.| |23|[ping](#ping)|N|Queues a ping to be sent to each connected peer.|
|24|[sendrawtransaction](#sendrawtransaction)|Submits the serialized, hex-encoded transaction to the local peer and relays it to the network.<br /><font color="orange">btcd does not yet implement the `allowhighfees` parameter, so it has no effect</font>| |24|[sendrawtransaction](#sendrawtransaction)|Y|Submits the serialized, hex-encoded transaction to the local peer and relays it to the network.<br /><font color="orange">btcd does not yet implement the `allowhighfees` parameter, so it has no effect</font>|
|25|[setgenerate](#setgenerate) |Set the server to generate coins (mine) or not.<br/>NOTE: Since btcd does not have the wallet integrated to provide payment addresses, btcd must be configured via the `--miningaddr` option to provide which payment addresses to pay created blocks to for this RPC to function.| |25|[setgenerate](#setgenerate) |N|Set the server to generate coins (mine) or not.<br/>NOTE: Since btcd does not have the wallet integrated to provide payment addresses, btcd must be configured via the `--miningaddr` option to provide which payment addresses to pay created blocks to for this RPC to function.|
|26|[stop](#stop)|Shutdown btcd.| |26|[stop](#stop)|N|Shutdown btcd.|
|27|[submitblock](#submitblock)|Attempts to submit a new serialized, hex-encoded block to the network.| |27|[submitblock](#submitblock)|Y|Attempts to submit a new serialized, hex-encoded block to the network.|
|28|[validateaddress](#validateaddress)|Verifies the given address is valid. NOTE: Since btcd does not have a wallet integrated, btcd will only return whether the address is valid or not.| |28|[validateaddress](#validateaddress)|Y|Verifies the given address is valid. NOTE: Since btcd does not have a wallet integrated, btcd will only return whether the address is valid or not.|
|29|[verifychain](#verifychain)|Verifies the block chain database.| |29|[verifychain](#verifychain)|N|Verifies the block chain database.|


<a name="MethodDetails" /> <a name="MethodDetails" />
**5.2 Method Details**<br /> **5.2 Method Details**<br />
Expand Down Expand Up @@ -544,12 +547,12 @@ the method name for further details such as parameter and return information.


The following is an overview of the RPC methods which are implemented by btcd, but not the original bitcoind client. Click the method name for further details such as parameter and return information. The following is an overview of the RPC methods which are implemented by btcd, but not the original bitcoind client. Click the method name for further details such as parameter and return information.


|#|Method|Description| |#|Method|Safe for limited user?|Description|
|---|------|-----------| |---|------|----------|-----------|
|1|[debuglevel](#debuglevel)|Dynamically changes the debug logging level.| |1|[debuglevel](#debuglevel)|N|Dynamically changes the debug logging level.|
|2|[getbestblock](#getbestblock)|Get block height and hash of best block in the main chain.|None| |2|[getbestblock](#getbestblock)|Y|Get block height and hash of best block in the main chain.|None|
|3|[getcurrentnet](#getcurrentnet)|Get bitcoin network btcd is running on.|None| |3|[getcurrentnet](#getcurrentnet)|Y|Get bitcoin network btcd is running on.|None|
|4|[searchrawtransactions](#searchrawtransactions)|Query for transactions related to a particular address.|None| |4|[searchrawtransactions](#searchrawtransactions)|Y|Query for transactions related to a particular address.|None|


<a name="ExtMethodDetails" /> <a name="ExtMethodDetails" />
**6.2 Method Details**<br /> **6.2 Method Details**<br />
Expand Down Expand Up @@ -612,7 +615,8 @@ The following is an overview of the RPC methods which are implemented by btcd, b
<a name="WSExtMethodOverview" /> <a name="WSExtMethodOverview" />
**7.1 Method Overview**<br /> **7.1 Method Overview**<br />


The following is an overview of the RPC method requests available exclusively to Websocket clients. Click the method name for further details such as parameter and return information. The following is an overview of the RPC method requests available exclusively to Websocket clients. All of these RPC methods are available to the limited
user. Click the method name for further details such as parameter and return information.


|#|Method|Description|Notifications| |#|Method|Description|Notifications|
|---|------|-----------|-------------| |---|------|-----------|-------------|
Expand Down

0 comments on commit 4a1445a

Please sign in to comment.