Skip to content

Commit

Permalink
Fixed protected mode access
Browse files Browse the repository at this point in the history
  • Loading branch information
dominicletz committed Jun 28, 2020
1 parent ce6d8cd commit abffe3f
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 119 deletions.
85 changes: 29 additions & 56 deletions cmd/diode/diode.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"os/signal"
"runtime"
"runtime/pprof"
"sort"
"strings"
"sync"
"syscall"
Expand Down Expand Up @@ -104,17 +105,8 @@ func diode() (status int) {
mfd.Close()
}

if cfg.Command == "config" {
status = doConfig(cfg)
return
}

{
lvbn, lvbh := rpc.LastValid()
printLabel("Last valid block", fmt.Sprintf("%v %v", lvbn, util.EncodeToString(lvbh[:])))

cfg.ClientAddr = util.PubkeyToAddress(rpc.LoadClientPubKey())
printLabel("Client address", cfg.ClientAddr.HexString())

fleetAddr, err := db.DB.Get("fleet")
if err != nil {
Expand All @@ -130,9 +122,18 @@ func diode() (status int) {
} else {
copy(cfg.FleetAddr[:], fleetAddr)
}
printLabel("Fleet address", cfg.FleetAddr.HexString())
}

if cfg.Command == "config" {
status = doConfig(cfg)
return
}

lvbn, lvbh := rpc.LastValid()
printLabel("Last valid block", fmt.Sprintf("%v %v", lvbn, util.EncodeToString(lvbh[:])))
printLabel("Client address", cfg.ClientAddr.HexString())
printLabel("Fleet address", cfg.FleetAddr.HexString())

// Connect to first server to respond
wg := &sync.WaitGroup{}
rpcAddrLen := len(cfg.RemoteRPCAddrs)
Expand Down Expand Up @@ -173,17 +174,9 @@ func diode() (status int) {
status = 129
return
}
lvbn, _ := rpc.LastValid()
lvbn, lvbh = rpc.LastValid()
cfg.Logger.Info(fmt.Sprintf("Network is validated, last valid block number: %d", lvbn))

// check device access to fleet contract and registry
clientAddr, err := client.GetClientAddress()
if err != nil {
cfg.Logger.Error(err.Error())
status = 129
return
}

if cfg.Command == "reset" {
if cfg.Experimental {
status = doInitExp(cfg, client)
Expand All @@ -204,7 +197,7 @@ func diode() (status int) {
}

// check device whitelist
isDeviceWhitelisted, err := client.IsDeviceWhitelisted(clientAddr)
isDeviceWhitelisted, err := client.IsDeviceWhitelisted(cfg.FleetAddr, cfg.ClientAddr)
if err != nil {
if err.Error() == "account does not exist" {
cfg.Logger.Warn("Device was not whitelisted, if you did whitelist device, please wait for 6 block confirmation, this can take up to a minute.")
Expand Down Expand Up @@ -337,11 +330,15 @@ func doConfig(cfg *config.Config) (status int) {

if cfg.ConfigList || !activity {
printLabel("<KEY>", "<VALUE>")
for _, name := range db.DB.List() {
list := db.DB.List()
sort.Strings(list)
for _, name := range list {
label := "<********************************>"
value, err := db.DB.Get(name)
if err == nil {
if name == "private" {
printLabel("<address>", cfg.ClientAddr.HexString())

if cfg.ConfigUnsafe {
block, _ := pem.Decode(value)
if block == nil {
Expand Down Expand Up @@ -389,21 +386,13 @@ func doInit(cfg *config.Config, client *rpc.RPCClient) (status int) {
status = 129
return
}
var act *edge.Account
clientAddr, err := client.GetClientAddress()
if err != nil {
printError("Couldn't load own address", err)
status = 129
return
}

act, _ = client.GetValidAccount(uint64(bn), clientAddr)
act, _ := client.GetValidAccount(uint64(bn), cfg.ClientAddr)
if act == nil {
nonce = 0
} else {
nonce = uint64(act.Nonce)
}
deployData, err := fleetContract.DeployFleetContract(cfg.RegistryAddr, clientAddr, clientAddr)
deployData, err := fleetContract.DeployFleetContract(cfg.RegistryAddr, cfg.ClientAddr, cfg.ClientAddr)
if err != nil {
printError("Cannot create deploy contract data: ", err)
status = 129
Expand All @@ -421,14 +410,14 @@ func doInit(cfg *config.Config, client *rpc.RPCClient) (status int) {
status = 129
return
}
fleetAddr := util.CreateAddress(clientAddr, nonce)
fleetAddr := util.CreateAddress(cfg.ClientAddr, nonce)
printLabel("New fleet address", fleetAddr.HexString())
printInfo("Waiting for block to be confirmed - this can take up to a minute")
watchAccount(client, fleetAddr)
printInfo("Created fleet contract successfully")
// generate fleet address
// send device whitelist transaction
whitelistData, _ := fleetContract.SetDeviceWhitelist(clientAddr, true)
whitelistData, _ := fleetContract.SetDeviceWhitelist(cfg.ClientAddr, true)
ntx := edge.NewTransaction(nonce+1, 0, 10000000, fleetAddr, 0, whitelistData, 0)
res, err = client.SendTransaction(ntx)
if err != nil {
Expand All @@ -441,7 +430,7 @@ func doInit(cfg *config.Config, client *rpc.RPCClient) (status int) {
status = 129
return
}
printLabel("Whitelisting device: ", clientAddr.HexString())
printLabel("Whitelisting device: ", cfg.ClientAddr.HexString())
printInfo("Waiting for block to be confirmed - this can take up to a minute")
watchAccount(client, fleetAddr)
printInfo("Whitelisted device successfully")
Expand Down Expand Up @@ -478,21 +467,13 @@ func doInitExp(cfg *config.Config, client *rpc.RPCClient) (status int) {
status = 129
return
}
var act *edge.Account
clientAddr, err := client.GetClientAddress()
if err != nil {
printError("Couldn't load own address", err)
status = 129
return
}

act, _ = client.GetValidAccount(uint64(bn), clientAddr)
act, _ := client.GetValidAccount(uint64(bn), cfg.ClientAddr)
if act == nil {
nonce = 0
} else {
nonce = uint64(act.Nonce)
}
deployData, err := fleetContract.DeployFleetContract(cfg.RegistryAddr, clientAddr, clientAddr)
deployData, err := fleetContract.DeployFleetContract(cfg.RegistryAddr, cfg.ClientAddr, cfg.ClientAddr)
if err != nil {
printError("Cannot create deploy contract data: ", err)
status = 129
Expand All @@ -510,11 +491,11 @@ func doInitExp(cfg *config.Config, client *rpc.RPCClient) (status int) {
status = 129
return
}
fleetAddr := util.CreateAddress(clientAddr, nonce)
fleetAddr := util.CreateAddress(cfg.ClientAddr, nonce)
printLabel("New fleet address", fleetAddr.HexString())
// generate fleet address
// send device whitelist transaction
whitelistData, _ := fleetContract.SetDeviceWhitelist(clientAddr, true)
whitelistData, _ := fleetContract.SetDeviceWhitelist(cfg.ClientAddr, true)
ntx := edge.NewTransaction(nonce+1, 0, 10000000, fleetAddr, 0, whitelistData, 0)
res, err = client.SendTransaction(ntx)
if err != nil {
Expand All @@ -527,7 +508,7 @@ func doInitExp(cfg *config.Config, client *rpc.RPCClient) (status int) {
status = 129
return
}
printLabel("Whitelisting device: ", clientAddr.HexString())
printLabel("Whitelisting device: ", cfg.ClientAddr.HexString())
printInfo("Waiting for block to be confirmed - this can take up to a minute")
watchAccount(client, fleetAddr)
printInfo("Created fleet contract and whitelisted device successfully")
Expand Down Expand Up @@ -571,15 +552,7 @@ func doBNS(cfg *config.Config, client *rpc.RPCClient) (status int) {
}

if len(registerPair) == 2 {
var act *edge.Account
clientAddr, err := client.GetClientAddress()
if err != nil {
printError("Couldn't load own address", err)
status = 129
return
}

act, _ = client.GetValidAccount(uint64(bn), clientAddr)
act, _ := client.GetValidAccount(uint64(bn), cfg.ClientAddr)
if act == nil {
nonce = 0
} else {
Expand Down
2 changes: 1 addition & 1 deletion rpc/bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func (rpcClient *RPCClient) handleInboundRequest(inboundRequest interface{}) {

if !publishedPort.IsWhitelisted(portOpen.DeviceID) {
if publishedPort.Mode == config.ProtectedPublishedMode {
isAccessWhilisted, err := rpcClient.IsAccessWhitelisted(rpcClient.Config.FleetAddr, portOpen.DeviceID)
isAccessWhilisted, err := rpcClient.IsDeviceWhitelisted(rpcClient.Config.FleetAddr, portOpen.DeviceID)
if err != nil || !isAccessWhilisted {
err := fmt.Errorf("device %x is not in the whitelist (1)", portOpen.DeviceID)
rpcClient.ResponsePortOpen(portOpen, err)
Expand Down
49 changes: 7 additions & 42 deletions rpc/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ var (

// RPCConfig struct for rpc client
type RPCConfig struct {
ClientAddr Address
RegistryAddr Address
FleetAddr Address
Blacklists map[Address]bool
Expand Down Expand Up @@ -127,11 +128,6 @@ func (rpcClient *RPCClient) Host() string {
return rpcClient.s.addr
}

// GetClientAddress returns client address
func (rpcClient *RPCClient) GetClientAddress() (util.Address, error) {
return rpcClient.s.GetClientAddress()
}

// GetDeviceKey returns device key of given ref
func (rpcClient *RPCClient) GetDeviceKey(ref string) string {
prefixByt, err := rpcClient.s.GetServerID()
Expand Down Expand Up @@ -560,11 +556,7 @@ func (rpcClient *RPCClient) newTicket() (*edge.DeviceTicket, error) {
if err != nil {
return nil, err
}
deviceID, err := rpcClient.s.GetClientAddress()
if err != nil {
return nil, err
}
if !ticket.ValidateDeviceSig(deviceID) {
if !ticket.ValidateDeviceSig(rpcClient.Config.ClientAddr) {
return nil, fmt.Errorf("ticket not verifyable")
}

Expand All @@ -585,16 +577,10 @@ func (rpcClient *RPCClient) submitTicket(ticket *edge.DeviceTicket) error {
lastTicket.ServerID = sid
lastTicket.FleetAddr = rpcClient.Config.FleetAddr

addr, err := rpcClient.s.GetClientAddress()
if err != nil {
// rpcClient.s.Logger.Error(fmt.Sprintf("SubmitTicket can't identify self: %s", err.Error()))
return err
}

if !lastTicket.ValidateDeviceSig(addr) {
if !lastTicket.ValidateDeviceSig(rpcClient.Config.ClientAddr) {
lastTicket.LocalAddr = util.DecodeForce(lastTicket.LocalAddr)
}
if lastTicket.ValidateDeviceSig(addr) {
if lastTicket.ValidateDeviceSig(rpcClient.Config.ClientAddr) {
rpcClient.s.totalBytes = lastTicket.TotalBytes + 1024
rpcClient.s.totalConnections = lastTicket.TotalConnections + 1
err = rpcClient.SubmitNewTicket()
Expand Down Expand Up @@ -827,33 +813,12 @@ func (rpcClient *RPCClient) ResolveBlockHash(blockNumber uint64) (blockHash []by
return
}

/**
* Contract api
* Seems fleet contract with rpcclient providor cause include cycle issue.
* Note: always return true if client use developer fleet
* Maybe another middle struct?
* TODO: should refactor this
*/
// IsDeviceWhitelisted returns is given address whitelisted
func (rpcClient *RPCClient) IsDeviceWhitelisted(addr [20]byte) (bool, error) {
if rpcClient.Config.FleetAddr == DefaultFleetAddr {
func (rpcClient *RPCClient) IsDeviceWhitelisted(fleetAddr Address, clientAddr Address) (bool, error) {
if fleetAddr == DefaultFleetAddr {
return true, nil
}
key := contract.DeviceWhitelistKey(addr)
raw, err := rpcClient.GetAccountValueRaw(0, rpcClient.Config.FleetAddr, key)
if err != nil {
return false, err
}
return (util.BytesToInt(raw) == 1), nil
}

// IsAccessWhitelisted returns is given address whitelisted
func (rpcClient *RPCClient) IsAccessWhitelisted(fleetAddr Address, clientAddr Address) (bool, error) {
deviceAddr, err := rpcClient.s.GetClientAddress()
if err != nil {
return false, err
}
key := contract.AccessWhitelistKey(deviceAddr, clientAddr)
key := contract.DeviceWhitelistKey(clientAddr)
raw, err := rpcClient.GetAccountValueRaw(0, fleetAddr, key)
if err != nil {
return false, err
Expand Down
21 changes: 1 addition & 20 deletions rpc/ssl.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,17 +226,6 @@ func (s *SSL) GetClientPrivateKey() (*ecdsa.PrivateKey, error) {
return clientPrivKey, nil
}

// GetClientPubKey returns client uncompressed public key
func (s *SSL) GetClientPubKey() ([]byte, error) {
privKey, err := s.GetClientPrivateKey()
if err != nil {
return nil, err
}
// uncompressed
clientPubKey := crypto.MarshalPubkey(&privKey.PublicKey)
return clientPubKey, nil
}

// LoadClientPubKey loads the clients public key from the database
func LoadClientPubKey() []byte {
kd := EnsurePrivatePEM()
Expand All @@ -249,15 +238,6 @@ func LoadClientPubKey() []byte {
return clientPubKey
}

// GetClientAddress returns client address
func (s *SSL) GetClientAddress() (util.Address, error) {
clientPubKey, err := s.GetClientPubKey()
if err != nil {
return [20]byte{}, err
}
return util.PubkeyToAddress(clientPubKey), nil
}

func (s *SSL) incrementTotalConnections(n int) {
s.rm.Lock()
defer s.rm.Unlock()
Expand Down Expand Up @@ -406,6 +386,7 @@ func DoConnect(host string, config *config.Config, pool *DataPool) (*RPCClient,
}

rpcConfig := &RPCConfig{
ClientAddr: config.ClientAddr,
RegistryAddr: config.RegistryAddr,
FleetAddr: config.FleetAddr,
Blacklists: config.Blacklists,
Expand Down

0 comments on commit abffe3f

Please sign in to comment.