add TlsRpcCommand and TlsRawRpcCommand.
These act the same as the !tls versions of this code but they take a PEM encoded certificate chain to be used to verify certificates (ca verified certs could use /etc/ssl/certs.pem) and a parameter to skip cert verification and will use https internally.
This commit is contained in:
parent
606262514b
commit
e43c79c74d
3 changed files with 56 additions and 5 deletions
|
@ -51,7 +51,7 @@ func TestJsonRpcSend(t *testing.T) {
|
|||
password := "something"
|
||||
server := "invalid"
|
||||
var message []byte
|
||||
_, err := jsonRpcSend(user, password, server, message)
|
||||
_, err := jsonRpcSend(user, password, server, message, false, nil, false)
|
||||
if err == nil {
|
||||
t.Errorf("Should fail when it cannot connect.")
|
||||
}
|
||||
|
|
37
jsonapi.go
37
jsonapi.go
|
@ -872,16 +872,32 @@ func JSONGetMethod(message []byte) (string, error) {
|
|||
return method, err
|
||||
}
|
||||
|
||||
// TlsRpcCommand takes a message generated from one of the routines above
|
||||
// along with the login/server information and any relavent PEM encoded
|
||||
// certificates chains. It sends the command via https and returns a go struct
|
||||
// with the result.
|
||||
func TlsRpcCommand(user string, password string, server string, message []byte,
|
||||
certificates []byte, skipverify bool) (Reply, error) {
|
||||
return rpcCommand(user, password, server, message, true, certificates,
|
||||
skipverify)
|
||||
}
|
||||
|
||||
// RpcCommand takes a message generated from one of the routines above
|
||||
// along with the login/server info, sends it, and gets a reply, returning
|
||||
// a go struct with the result.
|
||||
func RpcCommand(user string, password string, server string, message []byte) (Reply, error) {
|
||||
return rpcCommand(user, password, server, message, false, nil, false)
|
||||
}
|
||||
|
||||
func rpcCommand(user string, password string, server string, message []byte,
|
||||
https bool, certificates []byte, skipverify bool) (Reply, error) {
|
||||
var result Reply
|
||||
method, err := JSONGetMethod(message)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
body, err := RpcRawCommand(user, password, server, message)
|
||||
body, err := rpcRawCommand(user, password, server, message, https,
|
||||
certificates, skipverify)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error getting json reply: %v", err)
|
||||
return result, err
|
||||
|
@ -894,10 +910,26 @@ func RpcCommand(user string, password string, server string, message []byte) (Re
|
|||
return result, err
|
||||
}
|
||||
|
||||
// TlsRpcRawCommand takes a message generated from one of the routines above
|
||||
// along with the login,server info and PEM encoded certificate chains for the
|
||||
// server sends it, and gets a reply, returning
|
||||
// the raw []byte response for use with ReadResultCmd.
|
||||
func TlsRpcRawCommand(user string, password string, server string,
|
||||
message []byte, certificates []byte, skipverify bool) ([]byte, error) {
|
||||
return rpcRawCommand(user, password, server, message, true,
|
||||
certificates, skipverify)
|
||||
}
|
||||
|
||||
// RpcRawCommand takes a message generated from one of the routines above
|
||||
// along with the login/server info, sends it, and gets a reply, returning
|
||||
// the raw []byte response for use with ReadResultCmd.
|
||||
func RpcRawCommand(user string, password string, server string, message []byte) ([]byte, error) {
|
||||
return rpcRawCommand(user, password, server, message, false, nil, false)
|
||||
}
|
||||
|
||||
// rpcRawCommand is a helper function for the above two functions.
|
||||
func rpcRawCommand(user string, password string, server string,
|
||||
message []byte, https bool, certificates []byte, skipverify bool) ([]byte, error) {
|
||||
var result []byte
|
||||
var msg interface{}
|
||||
err := json.Unmarshal(message, &msg)
|
||||
|
@ -905,7 +937,8 @@ func RpcRawCommand(user string, password string, server string, message []byte)
|
|||
err := fmt.Errorf("Error, message does not appear to be valid json: %v", err)
|
||||
return result, err
|
||||
}
|
||||
resp, err := jsonRpcSend(user, password, server, message)
|
||||
resp, err := jsonRpcSend(user, password, server, message, https,
|
||||
certificates, skipverify)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error sending json message: " + err.Error())
|
||||
return result, err
|
||||
|
|
22
jsonfxns.go
22
jsonfxns.go
|
@ -6,6 +6,9 @@ package btcjson
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
_ "crypto/sha512"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -32,9 +35,24 @@ func MarshallAndSend(rawReply Reply, w io.Writer) (string, error) {
|
|||
// and ip/port and then send the supplied message. This uses net/http rather
|
||||
// than net/rpc/jsonrpc since that one doesn't support http connections and is
|
||||
// therefore useless.
|
||||
func jsonRpcSend(user string, password string, server string, message []byte) (*http.Response, error) {
|
||||
func jsonRpcSend(user string, password string, server string, message []byte,
|
||||
https bool, certificates []byte, skipverify bool) (*http.Response, error) {
|
||||
client := &http.Client{}
|
||||
protocol := "http"
|
||||
if https {
|
||||
pool := x509.NewCertPool()
|
||||
pool.AppendCertsFromPEM(certificates)
|
||||
|
||||
config := &tls.Config{
|
||||
InsecureSkipVerify: skipverify,
|
||||
RootCAs: pool,
|
||||
}
|
||||
transport := &http.Transport{TLSClientConfig: config}
|
||||
client.Transport = transport
|
||||
protocol = "https"
|
||||
}
|
||||
credentials := user + ":" + password
|
||||
resp, err := http.Post("http://"+credentials+"@"+server,
|
||||
resp, err := client.Post(protocol+"://"+credentials+"@"+server,
|
||||
"application/json", bytes.NewBuffer(message))
|
||||
if err != nil {
|
||||
// We do not want to log the username/password in the errors.
|
||||
|
|
Loading…
Reference in a new issue