mirror of
https://github.com/cwinfo/yggdrasil-go.git
synced 2024-11-22 15:20:30 +00:00
Optional peer authentication, if non-empty then incoming TCP and all UDP peers must match one of these box keys
This commit is contained in:
parent
5962d009a5
commit
6026e0a014
@ -5,6 +5,7 @@ type NodeConfig struct {
|
|||||||
Listen string
|
Listen string
|
||||||
AdminListen string
|
AdminListen string
|
||||||
Peers []string
|
Peers []string
|
||||||
|
PeerBoxPubs []string
|
||||||
BoxPub string
|
BoxPub string
|
||||||
BoxPriv string
|
BoxPriv string
|
||||||
SigPub string
|
SigPub string
|
||||||
|
@ -397,6 +397,12 @@ func (c *Core) DEBUG_setIfceExpr(expr *regexp.Regexp) {
|
|||||||
c.ifceExpr = expr
|
c.ifceExpr = expr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Core) DEBUG_addAuthBoxPub(boxBytes []byte) {
|
||||||
|
var box boxPubKey
|
||||||
|
copy(box[:], boxBytes)
|
||||||
|
c.peers.authBoxPubs[box] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
func DEBUG_simLinkPeers(p, q *peer) {
|
func DEBUG_simLinkPeers(p, q *peer) {
|
||||||
|
@ -30,9 +30,10 @@ import "math"
|
|||||||
//import "fmt"
|
//import "fmt"
|
||||||
|
|
||||||
type peers struct {
|
type peers struct {
|
||||||
core *Core
|
core *Core
|
||||||
mutex sync.Mutex // Synchronize writes to atomic
|
authBoxPubs map[boxPubKey]struct{}
|
||||||
ports atomic.Value //map[Port]*peer, use CoW semantics
|
mutex sync.Mutex // Synchronize writes to atomic
|
||||||
|
ports atomic.Value //map[Port]*peer, use CoW semantics
|
||||||
//ports map[Port]*peer
|
//ports map[Port]*peer
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,6 +42,12 @@ func (ps *peers) init(c *Core) {
|
|||||||
defer ps.mutex.Unlock()
|
defer ps.mutex.Unlock()
|
||||||
ps.putPorts(make(map[switchPort]*peer))
|
ps.putPorts(make(map[switchPort]*peer))
|
||||||
ps.core = c
|
ps.core = c
|
||||||
|
ps.authBoxPubs = make(map[boxPubKey]struct{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ps *peers) isAuthBoxPub(box *boxPubKey) bool {
|
||||||
|
_, isIn := ps.authBoxPubs[*box]
|
||||||
|
return isIn || len(ps.authBoxPubs) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ps *peers) getPorts() map[switchPort]*peer {
|
func (ps *peers) getPorts() map[switchPort]*peer {
|
||||||
|
@ -62,7 +62,7 @@ func (iface *tcpInterface) listener() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
go iface.handler(sock)
|
go iface.handler(sock, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ func (iface *tcpInterface) callWithConn(conn net.Conn) {
|
|||||||
delete(iface.calls, raddr)
|
delete(iface.calls, raddr)
|
||||||
iface.mutex.Unlock()
|
iface.mutex.Unlock()
|
||||||
}()
|
}()
|
||||||
iface.handler(conn)
|
iface.handler(conn, false)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
@ -106,12 +106,12 @@ func (iface *tcpInterface) call(saddr string) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
iface.handler(conn)
|
iface.handler(conn, false)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (iface *tcpInterface) handler(sock net.Conn) {
|
func (iface *tcpInterface) handler(sock net.Conn, incoming bool) {
|
||||||
defer sock.Close()
|
defer sock.Close()
|
||||||
// Get our keys
|
// Get our keys
|
||||||
keys := []byte{}
|
keys := []byte{}
|
||||||
@ -150,6 +150,15 @@ func (iface *tcpInterface) handler(sock net.Conn) {
|
|||||||
if equiv(info.sig[:], iface.core.sigPub[:]) {
|
if equiv(info.sig[:], iface.core.sigPub[:]) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// Check if we're authorized to connect to this key / IP
|
||||||
|
if incoming && !iface.core.peers.isAuthBoxPub(&info.box) {
|
||||||
|
// Allow unauthorized peers if they're link-local
|
||||||
|
raddrStr, _, _ := net.SplitHostPort(sock.RemoteAddr().String())
|
||||||
|
raddr := net.ParseIP(raddrStr)
|
||||||
|
if !raddr.IsLinkLocalUnicast() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
// Check if we already have a connection to this node, close and block if yes
|
// Check if we already have a connection to this node, close and block if yes
|
||||||
info.localAddr, _, _ = net.SplitHostPort(sock.LocalAddr().String())
|
info.localAddr, _, _ = net.SplitHostPort(sock.LocalAddr().String())
|
||||||
info.remoteAddr, _, _ = net.SplitHostPort(sock.RemoteAddr().String())
|
info.remoteAddr, _, _ = net.SplitHostPort(sock.RemoteAddr().String())
|
||||||
|
@ -204,6 +204,14 @@ func (iface *udpInterface) handleKeys(msg []byte, addr connAddr) {
|
|||||||
iface.mutex.RUnlock()
|
iface.mutex.RUnlock()
|
||||||
if !isIn {
|
if !isIn {
|
||||||
udpAddr := addr.toUDPAddr()
|
udpAddr := addr.toUDPAddr()
|
||||||
|
// Check if we're authorized to connect to this key / IP
|
||||||
|
// TODO monitor and always allow outgoing connections
|
||||||
|
if !iface.core.peers.isAuthBoxPub(&ks.box) {
|
||||||
|
// Allow unauthorized peers if they're link-local
|
||||||
|
if !udpAddr.IP.IsLinkLocalUnicast() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
themNodeID := getNodeID(&ks.box)
|
themNodeID := getNodeID(&ks.box)
|
||||||
themAddr := address_addrForNodeID(themNodeID)
|
themAddr := address_addrForNodeID(themNodeID)
|
||||||
themAddrString := net.IP(themAddr[:]).String()
|
themAddrString := net.IP(themAddr[:]).String()
|
||||||
|
@ -58,6 +58,13 @@ func (n *node) init(cfg *nodeConfig, logger *log.Logger) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
n.core.DEBUG_setIfceExpr(ifceExpr)
|
n.core.DEBUG_setIfceExpr(ifceExpr)
|
||||||
|
for _, pBoxStr := range cfg.PeerBoxPubs {
|
||||||
|
pbox, err := hex.DecodeString(pBoxStr)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
n.core.DEBUG_addAuthBoxPub(pbox)
|
||||||
|
}
|
||||||
|
|
||||||
logger.Println("Starting interface...")
|
logger.Println("Starting interface...")
|
||||||
n.core.DEBUG_setupAndStartGlobalTCPInterface(cfg.Listen) // Listen for peers on TCP
|
n.core.DEBUG_setupAndStartGlobalTCPInterface(cfg.Listen) // Listen for peers on TCP
|
||||||
|
Loading…
Reference in New Issue
Block a user