mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 10:22:23 +00:00
Merge 0f6290fe46 into f1986f86f2
This commit is contained in:
commit
e9a6e2b3e8
3 changed files with 116 additions and 0 deletions
|
|
@ -69,6 +69,7 @@ const (
|
||||||
DiscUnexpectedIdentity
|
DiscUnexpectedIdentity
|
||||||
DiscSelf
|
DiscSelf
|
||||||
DiscReadTimeout
|
DiscReadTimeout
|
||||||
|
DiscPermissionFailed
|
||||||
DiscSubprotocolError = 0x10
|
DiscSubprotocolError = 0x10
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
79
p2p/permissions.go
Normal file
79
p2p/permissions.go
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
package p2p
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
NODE_NAME_LENGTH = 32
|
||||||
|
PERMISSIONED_CONFIG = "permissioned-nodes.json"
|
||||||
|
)
|
||||||
|
|
||||||
|
// check if a given node is permissioned to connect to the change
|
||||||
|
func isNodePermissioned(nodename string, currentNode string, datadir string, direction string) bool {
|
||||||
|
|
||||||
|
var permissionedList []string
|
||||||
|
nodes := parsePermissionedNodes(datadir)
|
||||||
|
for _, v := range nodes {
|
||||||
|
permissionedList = append(permissionedList, v.ID.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug("isNodePermissioned", "permissionedList", permissionedList)
|
||||||
|
for _, v := range permissionedList {
|
||||||
|
if v == nodename {
|
||||||
|
log.Debug("isNodePermissioned", "connection", direction, "nodename", nodename[:NODE_NAME_LENGTH], "ALLOWED-BY", currentNode[:NODE_NAME_LENGTH])
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
log.Debug("isNodePermissioned", "connection", direction, "nodename", nodename[:NODE_NAME_LENGTH], "DENIED-BY", currentNode[:NODE_NAME_LENGTH])
|
||||||
|
}
|
||||||
|
log.Debug("isNodePermissioned", "connection", direction, "nodename", nodename[:NODE_NAME_LENGTH], "DENIED-BY", currentNode[:NODE_NAME_LENGTH])
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
//this is a shameless copy from the config.go. It is a duplication of the code
|
||||||
|
//for the timebeing to allow reload of the permissioned nodes while the server is running
|
||||||
|
|
||||||
|
func parsePermissionedNodes(DataDir string) []*discover.Node {
|
||||||
|
|
||||||
|
log.Debug("parsePermissionedNodes", "DataDir", DataDir, "file", PERMISSIONED_CONFIG)
|
||||||
|
|
||||||
|
path := filepath.Join(DataDir, PERMISSIONED_CONFIG)
|
||||||
|
if _, err := os.Stat(path); err != nil {
|
||||||
|
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)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// Load the nodes from the config file
|
||||||
|
blob, err := ioutil.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("parsePermissionedNodes: Failed to access nodes", "err", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
nodelist := []string{}
|
||||||
|
if err := json.Unmarshal(blob, &nodelist); err != nil {
|
||||||
|
log.Error("parsePermissionedNodes: Failed to load nodes", "err", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// Interpret the list as a discovery node array
|
||||||
|
var nodes []*discover.Node
|
||||||
|
for _, url := range nodelist {
|
||||||
|
if url == "" {
|
||||||
|
log.Error("parsePermissionedNodes: Node URL blank")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
node, err := discover.ParseNode(url)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("parsePermissionedNodes: Node URL", "url", url, "err", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
//log.Error("json node: "+node.String())
|
||||||
|
nodes = append(nodes, node)
|
||||||
|
}
|
||||||
|
return nodes
|
||||||
|
}
|
||||||
|
|
@ -141,6 +141,10 @@ type Config struct {
|
||||||
|
|
||||||
// Logger is a custom logger to use with the p2p.Server.
|
// Logger is a custom logger to use with the p2p.Server.
|
||||||
Logger log.Logger `toml:",omitempty"`
|
Logger log.Logger `toml:",omitempty"`
|
||||||
|
|
||||||
|
EnableNodePermission bool `toml:",omitempty"`
|
||||||
|
|
||||||
|
DataDir string `toml:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Server manages all peer connections.
|
// Server manages all peer connections.
|
||||||
|
|
@ -820,6 +824,38 @@ func (srv *Server) setupConn(c *conn, flags connFlag, dialDest *discover.Node) e
|
||||||
srv.log.Trace("Failed RLPx handshake", "addr", c.fd.RemoteAddr(), "conn", c.flags, "err", err)
|
srv.log.Trace("Failed RLPx handshake", "addr", c.fd.RemoteAddr(), "conn", c.flags, "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//START Permissioning
|
||||||
|
currentNode := srv.NodeInfo().ID
|
||||||
|
cnodeName := srv.NodeInfo().Name
|
||||||
|
log.Trace("Quorum permissioning",
|
||||||
|
"EnableNodePermission", srv.EnableNodePermission,
|
||||||
|
"DataDir", srv.DataDir,
|
||||||
|
"Current Node ID", currentNode,
|
||||||
|
"Node Name", cnodeName,
|
||||||
|
"Dialed Dest", dialDest,
|
||||||
|
"Connection ID", c.id,
|
||||||
|
"Connection String", c.id.String())
|
||||||
|
|
||||||
|
|
||||||
|
log.Trace("Node Permissioning is Enabled.")
|
||||||
|
node := c.id.String()
|
||||||
|
direction := "INCOMING"
|
||||||
|
if dialDest != nil {
|
||||||
|
node = dialDest.ID.String()
|
||||||
|
direction = "OUTGOING"
|
||||||
|
log.Trace("Node Permissioning", "Connection Direction", direction)
|
||||||
|
}
|
||||||
|
|
||||||
|
//log.Error("entry permission check.")
|
||||||
|
if !isNodePermissioned(node, currentNode, srv.DataDir, direction) {
|
||||||
|
//log.Error("permission check failed.")
|
||||||
|
return DiscPermissionFailed
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//END Permissioning
|
||||||
|
|
||||||
clog := srv.log.New("id", c.id, "addr", c.fd.RemoteAddr(), "conn", c.flags)
|
clog := srv.log.New("id", c.id, "addr", c.fd.RemoteAddr(), "conn", c.flags)
|
||||||
// For dialed connections, check that the remote public key matches.
|
// For dialed connections, check that the remote public key matches.
|
||||||
if dialDest != nil && c.id != dialDest.ID {
|
if dialDest != nil && c.id != dialDest.ID {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue