github.com/corverroos/quorum@v21.1.0+incompatible/permission/core/permissions.go (about)

     1  package core
     2  
     3  import (
     4  	"encoding/json"
     5  	"io/ioutil"
     6  	"math/big"
     7  	"os"
     8  	"path/filepath"
     9  
    10  	"github.com/ethereum/go-ethereum/common"
    11  	"github.com/ethereum/go-ethereum/log"
    12  	"github.com/ethereum/go-ethereum/p2p/enode"
    13  	"github.com/ethereum/go-ethereum/params"
    14  )
    15  
    16  // check if a given node is permissioned to connect to the change
    17  func IsNodePermissioned(nodename string, currentNode string, datadir string, direction string) bool {
    18  	var permissionedList []string
    19  	nodes := ParsePermissionedNodes(datadir)
    20  	for _, v := range nodes {
    21  		permissionedList = append(permissionedList, v.ID().String())
    22  	}
    23  
    24  	log.Debug("IsNodePermissioned", "permissionedList", permissionedList)
    25  	for _, v := range permissionedList {
    26  		if v == nodename {
    27  			log.Debug("IsNodePermissioned", "connection", direction, "nodename", nodename[:params.NODE_NAME_LENGTH], "ALLOWED-BY", currentNode[:params.NODE_NAME_LENGTH])
    28  			// check if the node is blacklisted
    29  			return !isNodeBlackListed(nodename, datadir)
    30  		}
    31  	}
    32  	log.Debug("IsNodePermissioned", "connection", direction, "nodename", nodename[:params.NODE_NAME_LENGTH], "DENIED-BY", currentNode[:params.NODE_NAME_LENGTH])
    33  	return false
    34  }
    35  
    36  //this is a shameless copy from the config.go. It is a duplication of the code
    37  //for the timebeing to allow reload of the permissioned nodes while the server is running
    38  
    39  func ParsePermissionedNodes(DataDir string) []*enode.Node {
    40  
    41  	log.Debug("parsePermissionedNodes", "DataDir", DataDir, "file", params.PERMISSIONED_CONFIG)
    42  
    43  	path := filepath.Join(DataDir, params.PERMISSIONED_CONFIG)
    44  	if _, err := os.Stat(path); err != nil {
    45  		log.Error("Read Error for permissioned-nodes.json file. This is because 'permissioned' flag is specified but no permissioned-nodes.json file is present.", "err", err)
    46  		return nil
    47  	}
    48  	// Load the nodes from the config file
    49  	blob, err := ioutil.ReadFile(path)
    50  	if err != nil {
    51  		log.Error("parsePermissionedNodes: Failed to access nodes", "err", err)
    52  		return nil
    53  	}
    54  
    55  	nodelist := []string{}
    56  	if err := json.Unmarshal(blob, &nodelist); err != nil {
    57  		log.Error("parsePermissionedNodes: Failed to load nodes", "err", err)
    58  		return nil
    59  	}
    60  	// Interpret the list as a discovery node array
    61  	var nodes []*enode.Node
    62  	for _, url := range nodelist {
    63  		if url == "" {
    64  			log.Error("parsePermissionedNodes: Node URL blank")
    65  			continue
    66  		}
    67  		node, err := enode.ParseV4(url)
    68  		if err != nil {
    69  			log.Error("parsePermissionedNodes: Node URL", "url", url, "err", err)
    70  			continue
    71  		}
    72  		nodes = append(nodes, node)
    73  	}
    74  	return nodes
    75  }
    76  
    77  // This function checks if the node is black-listed
    78  func isNodeBlackListed(nodeName, dataDir string) bool {
    79  	log.Debug("isNodeBlackListed", "DataDir", dataDir, "file", params.BLACKLIST_CONFIG)
    80  
    81  	path := filepath.Join(dataDir, params.BLACKLIST_CONFIG)
    82  	if _, err := os.Stat(path); err != nil {
    83  		log.Debug("Read Error for disallowed-nodes.json file. disallowed-nodes.json file is not present.", "err", err)
    84  		return false
    85  	}
    86  	// Load the nodes from the config file
    87  	blob, err := ioutil.ReadFile(path)
    88  	if err != nil {
    89  		log.Debug("isNodeBlackListed: Failed to access nodes", "err", err)
    90  		return true
    91  	}
    92  
    93  	nodelist := []string{}
    94  	if err := json.Unmarshal(blob, &nodelist); err != nil {
    95  		log.Debug("parsePermissionedNodes: Failed to load nodes", "err", err)
    96  		return true
    97  	}
    98  
    99  	for _, v := range nodelist {
   100  		n, _ := enode.ParseV4(v)
   101  		if nodeName == n.ID().String() {
   102  			return true
   103  		}
   104  	}
   105  	return false
   106  }
   107  
   108  // function checks for account access to execute the transaction
   109  func CheckAccountPermission(from common.Address, to *common.Address, value *big.Int, data []byte, gas uint64, gasPrice *big.Int) error {
   110  	transactionType := ValueTransferTxn
   111  
   112  	if to == nil {
   113  		transactionType = ContractDeployTxn
   114  	} else if data != nil {
   115  		transactionType = ContractCallTxn
   116  	}
   117  
   118  	var toAcct common.Address
   119  
   120  	if to == nil {
   121  		toAcct = common.Address{}
   122  	} else {
   123  		toAcct = *to
   124  	}
   125  
   126  	return IsTransactionAllowed(from, toAcct, value, gasPrice, big.NewInt(int64(gas)), data, transactionType)
   127  }