mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 03:05:07 +03: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
					
				
					 6 changed files with 45 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -5,6 +5,7 @@ type NodeConfig struct {
 | 
			
		|||
	Listen      string
 | 
			
		||||
	AdminListen string
 | 
			
		||||
	Peers       []string
 | 
			
		||||
	PeerBoxPubs []string
 | 
			
		||||
	BoxPub      string
 | 
			
		||||
	BoxPriv     string
 | 
			
		||||
	SigPub      string
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -397,6 +397,12 @@ func (c *Core) DEBUG_setIfceExpr(expr *regexp.Regexp) {
 | 
			
		|||
	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) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,6 +31,7 @@ import "math"
 | 
			
		|||
 | 
			
		||||
type peers struct {
 | 
			
		||||
	core        *Core
 | 
			
		||||
	authBoxPubs map[boxPubKey]struct{}
 | 
			
		||||
	mutex       sync.Mutex   // Synchronize writes to atomic
 | 
			
		||||
	ports       atomic.Value //map[Port]*peer, use CoW semantics
 | 
			
		||||
	//ports map[Port]*peer
 | 
			
		||||
| 
						 | 
				
			
			@ -41,6 +42,12 @@ func (ps *peers) init(c *Core) {
 | 
			
		|||
	defer ps.mutex.Unlock()
 | 
			
		||||
	ps.putPorts(make(map[switchPort]*peer))
 | 
			
		||||
	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 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,7 +62,7 @@ func (iface *tcpInterface) listener() {
 | 
			
		|||
		if err != nil {
 | 
			
		||||
			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)
 | 
			
		||||
				iface.mutex.Unlock()
 | 
			
		||||
			}()
 | 
			
		||||
			iface.handler(conn)
 | 
			
		||||
			iface.handler(conn, false)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -106,12 +106,12 @@ func (iface *tcpInterface) call(saddr string) {
 | 
			
		|||
			if err != nil {
 | 
			
		||||
				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()
 | 
			
		||||
	// Get our keys
 | 
			
		||||
	keys := []byte{}
 | 
			
		||||
| 
						 | 
				
			
			@ -150,6 +150,15 @@ func (iface *tcpInterface) handler(sock net.Conn) {
 | 
			
		|||
	if equiv(info.sig[:], iface.core.sigPub[:]) {
 | 
			
		||||
		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
 | 
			
		||||
	info.localAddr, _, _ = net.SplitHostPort(sock.LocalAddr().String())
 | 
			
		||||
	info.remoteAddr, _, _ = net.SplitHostPort(sock.RemoteAddr().String())
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -204,6 +204,14 @@ func (iface *udpInterface) handleKeys(msg []byte, addr connAddr) {
 | 
			
		|||
	iface.mutex.RUnlock()
 | 
			
		||||
	if !isIn {
 | 
			
		||||
		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)
 | 
			
		||||
		themAddr := address_addrForNodeID(themNodeID)
 | 
			
		||||
		themAddrString := net.IP(themAddr[:]).String()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,6 +58,13 @@ func (n *node) init(cfg *nodeConfig, logger *log.Logger) {
 | 
			
		|||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
	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...")
 | 
			
		||||
	n.core.DEBUG_setupAndStartGlobalTCPInterface(cfg.Listen) // Listen for peers on TCP
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue