Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Whitelist feature for wallet #135

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 15 additions & 14 deletions jsonrpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,21 @@ import (

// RPCConfig is the configuration for the API handler
type RPCConfig struct {
WalletTLSEnable bool
WalletTLSKeyFile string
WalletTLSCertFile string
WalletRPCUser string
WalletRPCPassword string
WalletServer string
WalletTimeout time.Duration
WalletCORSDomains string
FactomdTLSEnable bool
FactomdTLSCertFile string
FactomdRPCUser string
FactomdRPCPassword string
FactomdServer string
FactomdTimeout time.Duration
WalletTLSEnable bool
WalletTLSKeyFile string
WalletTLSCertFile string
WalletRPCUser string
WalletRPCPassword string
WalletServer string
WalletTimeout time.Duration
WalletCORSDomains string
FactomdTLSEnable bool
FactomdTLSCertFile string
FactomdRPCUser string
FactomdRPCPassword string
FactomdServer string
FactomdTimeout time.Duration
WalletWhiteListEnable bool
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whitelist is a single word and should be camel cased Whitelist (like you did in other places actually)

}

func EncodeJSON(data interface{}) ([]byte, error) {
Expand Down
51 changes: 46 additions & 5 deletions wallet/wsapi/wsapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"fmt"
"io/ioutil"
"log"
"net"
"net/http"
"os"
"reflect"
Expand All @@ -35,11 +36,13 @@ import (
const APIVersion string = "2.0"

var (
webServer *web.Server
fctWallet *wallet.Wallet
rpcUser string
rpcPass string
authsha []byte
webServer *web.Server
fctWallet *wallet.Wallet
rpcUser string
rpcPass string
authsha []byte
whitelistEnable bool
whitelist []string
)

// httpBasicAuth returns the UTF-8 bytes of the HTTP Basic authentication
Expand Down Expand Up @@ -119,6 +122,7 @@ func Start(w *wallet.Wallet, net string, c factom.RPCConfig) {

rpcUser = c.WalletRPCUser
rpcPass = c.WalletRPCPassword
whitelistEnable = c.WalletWhiteListEnable

h := sha256.New()
h.Write(httpBasicAuth(rpcUser, rpcPass))
Expand Down Expand Up @@ -153,6 +157,38 @@ func Stop() {
webServer.Close()
}

func WhiteListIP(raw string) error {
ip := net.ParseIP(raw)
if ip == nil {
return errors.New("unable to parse IP")
}
whitelist = append(whitelist, ip.String())
return nil
}

func checkWhitelistHeader(r *http.Request) error {
if !whitelistEnable {
return nil
}

host, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
return errors.New("unable to determine ip address of " + r.RemoteAddr)
}

if host == "127.0.0.1" || host == "::1" {
return nil
}

for _, ip := range whitelist {
if ip == host {
return nil
}
}
fmt.Println("denied a connection from non-whitelisted ip:", r.RemoteAddr)
return errors.New("not whitelisted")
}

func checkAuthHeader(r *http.Request) error {
// Don't bother to check the autorization if the rpc user/pass is not
// specified.
Expand All @@ -178,6 +214,11 @@ func checkAuthHeader(r *http.Request) error {
}

func handleV2(ctx *web.Context) {
if err := checkWhitelistHeader(ctx.Request); err != nil {
http.Error(ctx.ResponseWriter, "401 Unauthorized.", http.StatusUnauthorized)
return
}

if err := checkAuthHeader(ctx.Request); err != nil {
remoteIP := ""
remoteIP += strings.Split(ctx.Request.RemoteAddr, ":")[0]
Expand Down