mirror of
https://github.com/cwinfo/yggdrasil-go.git
synced 2024-12-02 00:11:37 +00:00
move ckr checks into the tunConn code
This commit is contained in:
parent
b79829c43b
commit
4156aa3003
@ -132,23 +132,9 @@ func (c *cryptokey) isEnabled() bool {
|
|||||||
func (c *cryptokey) isValidLocalAddress(addr address.Address, addrlen int) bool {
|
func (c *cryptokey) isValidLocalAddress(addr address.Address, addrlen int) bool {
|
||||||
c.mutexlocals.RLock()
|
c.mutexlocals.RLock()
|
||||||
defer c.mutexlocals.RUnlock()
|
defer c.mutexlocals.RUnlock()
|
||||||
|
|
||||||
ip := net.IP(addr[:addrlen])
|
|
||||||
|
|
||||||
if addrlen == net.IPv6len {
|
|
||||||
// Does this match our node's address?
|
|
||||||
if bytes.Equal(addr[:16], c.tun.addr[:16]) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Does this match our node's subnet?
|
|
||||||
if bytes.Equal(addr[:8], c.tun.subnet[:8]) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Does it match a configured CKR source?
|
// Does it match a configured CKR source?
|
||||||
if c.isEnabled() {
|
if c.isEnabled() {
|
||||||
|
ip := net.IP(addr[:addrlen])
|
||||||
// Build our references to the routing sources
|
// Build our references to the routing sources
|
||||||
var routingsources *[]net.IPNet
|
var routingsources *[]net.IPNet
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/yggdrasil-network/yggdrasil-go/src/address"
|
"github.com/yggdrasil-network/yggdrasil-go/src/address"
|
||||||
|
"github.com/yggdrasil-network/yggdrasil-go/src/crypto"
|
||||||
"github.com/yggdrasil-network/yggdrasil-go/src/util"
|
"github.com/yggdrasil-network/yggdrasil-go/src/util"
|
||||||
"github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil"
|
"github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil"
|
||||||
"golang.org/x/net/icmp"
|
"golang.org/x/net/icmp"
|
||||||
@ -71,16 +72,62 @@ func (s *tunConn) reader() (err error) {
|
|||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
} else if len(bs) > 0 {
|
} else if len(bs) > 0 {
|
||||||
if bs[0]&0xf0 == 0x60 {
|
ipv4 := len(bs) > 20 && bs[0]&0xf0 == 0x40
|
||||||
switch {
|
ipv6 := len(bs) > 40 && bs[0]&0xf0 == 0x60
|
||||||
case bs[8] == 0x02 && !bytes.Equal(s.addr[:16], bs[8:24]): // source
|
isCGA := true
|
||||||
case bs[8] == 0x03 && !bytes.Equal(s.snet[:8], bs[8:16]): // source
|
// Check source addresses
|
||||||
case bs[24] == 0x02 && !bytes.Equal(s.tun.addr[:16], bs[24:40]): // destination
|
switch {
|
||||||
case bs[24] == 0x03 && !bytes.Equal(s.tun.subnet[:8], bs[24:32]): // destination
|
case ipv6 && bs[8] == 0x02 && bytes.Equal(s.addr[:16], bs[8:24]): // source
|
||||||
util.PutBytes(bs)
|
case ipv6 && bs[8] == 0x03 && bytes.Equal(s.snet[:8], bs[8:16]): // source
|
||||||
continue
|
default:
|
||||||
default:
|
isCGA = false
|
||||||
|
}
|
||||||
|
// Check destiantion addresses
|
||||||
|
switch {
|
||||||
|
case ipv6 && bs[24] == 0x02 && bytes.Equal(s.tun.addr[:16], bs[24:40]): // destination
|
||||||
|
case ipv6 && bs[24] == 0x03 && bytes.Equal(s.tun.subnet[:8], bs[24:32]): // destination
|
||||||
|
default:
|
||||||
|
isCGA = false
|
||||||
|
}
|
||||||
|
// Decide how to handle the packet
|
||||||
|
var skip bool
|
||||||
|
switch {
|
||||||
|
case isCGA: // Allowed
|
||||||
|
case s.tun.ckr.isEnabled() && (ipv4 || ipv6):
|
||||||
|
var srcAddr address.Address
|
||||||
|
var dstAddr address.Address
|
||||||
|
var addrlen int
|
||||||
|
if ipv4 {
|
||||||
|
copy(srcAddr[:], bs[12:16])
|
||||||
|
copy(dstAddr[:], bs[16:20])
|
||||||
|
addrlen = 4
|
||||||
}
|
}
|
||||||
|
if ipv6 {
|
||||||
|
copy(srcAddr[:], bs[8:24])
|
||||||
|
copy(dstAddr[:], bs[24:40])
|
||||||
|
addrlen = 16
|
||||||
|
}
|
||||||
|
if !s.tun.ckr.isValidLocalAddress(dstAddr, addrlen) {
|
||||||
|
// The destination address isn't in our CKR allowed range
|
||||||
|
skip = true
|
||||||
|
} else if key, err := s.tun.ckr.getPublicKeyForAddress(srcAddr, addrlen); err == nil {
|
||||||
|
srcNodeID := crypto.GetNodeID(&key)
|
||||||
|
if s.conn.RemoteAddr() == *srcNodeID {
|
||||||
|
// This is the one allowed CKR case, where source and destination addresses are both good
|
||||||
|
} else {
|
||||||
|
// The CKR key associated with this address doesn't match the sender's NodeID
|
||||||
|
skip = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We have no CKR route for this source address
|
||||||
|
skip = true
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
skip = true
|
||||||
|
}
|
||||||
|
if skip {
|
||||||
|
util.PutBytes(bs)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
s.tun.send <- bs
|
s.tun.send <- bs
|
||||||
s.stillAlive()
|
s.stillAlive()
|
||||||
@ -108,15 +155,62 @@ func (s *tunConn) writer() error {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("send closed")
|
return errors.New("send closed")
|
||||||
}
|
}
|
||||||
if bs[0]&0xf0 == 0x60 {
|
v4 := len(bs) > 20 && bs[0]&0xf0 == 0x40
|
||||||
switch {
|
v6 := len(bs) > 40 && bs[0]&0xf0 == 0x60
|
||||||
case bs[8] == 0x02 && !bytes.Equal(s.tun.addr[:16], bs[8:24]): // source
|
isCGA := true
|
||||||
case bs[8] == 0x03 && !bytes.Equal(s.tun.subnet[:8], bs[8:16]): // source
|
// Check source addresses
|
||||||
case bs[24] == 0x02 && !bytes.Equal(s.addr[:16], bs[24:40]): // destination
|
switch {
|
||||||
case bs[24] == 0x03 && !bytes.Equal(s.snet[:8], bs[24:32]): // destination
|
case v6 && bs[8] == 0x02 && bytes.Equal(s.tun.addr[:16], bs[8:24]): // source
|
||||||
continue
|
case v6 && bs[8] == 0x03 && bytes.Equal(s.tun.subnet[:8], bs[8:16]): // source
|
||||||
default:
|
default:
|
||||||
|
isCGA = false
|
||||||
|
}
|
||||||
|
// Check destiantion addresses
|
||||||
|
switch {
|
||||||
|
case v6 && bs[24] == 0x02 && bytes.Equal(s.addr[:16], bs[24:40]): // destination
|
||||||
|
case v6 && bs[24] == 0x03 && bytes.Equal(s.snet[:8], bs[24:32]): // destination
|
||||||
|
default:
|
||||||
|
isCGA = false
|
||||||
|
}
|
||||||
|
// Decide how to handle the packet
|
||||||
|
var skip bool
|
||||||
|
switch {
|
||||||
|
case isCGA: // Allowed
|
||||||
|
case s.tun.ckr.isEnabled() && (v4 || v6):
|
||||||
|
var srcAddr address.Address
|
||||||
|
var dstAddr address.Address
|
||||||
|
var addrlen int
|
||||||
|
if v4 {
|
||||||
|
copy(srcAddr[:], bs[12:16])
|
||||||
|
copy(dstAddr[:], bs[16:20])
|
||||||
|
addrlen = 4
|
||||||
}
|
}
|
||||||
|
if v6 {
|
||||||
|
copy(srcAddr[:], bs[8:24])
|
||||||
|
copy(dstAddr[:], bs[24:40])
|
||||||
|
addrlen = 16
|
||||||
|
}
|
||||||
|
if !s.tun.ckr.isValidLocalAddress(srcAddr, addrlen) {
|
||||||
|
// The source address isn't in our CKR allowed range
|
||||||
|
skip = true
|
||||||
|
} else if key, err := s.tun.ckr.getPublicKeyForAddress(dstAddr, addrlen); err == nil {
|
||||||
|
dstNodeID := crypto.GetNodeID(&key)
|
||||||
|
if s.conn.RemoteAddr() == *dstNodeID {
|
||||||
|
// This is the one allowed CKR case, where source and destination addresses are both good
|
||||||
|
} else {
|
||||||
|
// The CKR key associated with this address doesn't match the sender's NodeID
|
||||||
|
skip = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We have no CKR route for this destination address... why do we have the packet in the first place?
|
||||||
|
skip = true
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
skip = true
|
||||||
|
}
|
||||||
|
if skip {
|
||||||
|
util.PutBytes(bs)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
msg := yggdrasil.FlowKeyMessage{
|
msg := yggdrasil.FlowKeyMessage{
|
||||||
FlowKey: util.GetFlowKey(bs),
|
FlowKey: util.GetFlowKey(bs),
|
||||||
|
@ -2,7 +2,6 @@ package tuntap
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -21,62 +20,6 @@ func (tun *TunAdapter) writer() error {
|
|||||||
if n == 0 {
|
if n == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
var srcAddr address.Address
|
|
||||||
var dstAddr address.Address
|
|
||||||
var addrlen int
|
|
||||||
// Check whether the packet is IPv4, IPv6 or neither
|
|
||||||
if b[0]&0xf0 == 0x60 {
|
|
||||||
// IPv6 packet found
|
|
||||||
if len(b) < 40 {
|
|
||||||
// Packet was too short
|
|
||||||
util.PutBytes(b)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// Extract the IPv6 addresses
|
|
||||||
copy(srcAddr[:16], b[8:24])
|
|
||||||
copy(dstAddr[:16], b[24:40])
|
|
||||||
addrlen = 16
|
|
||||||
} else if b[0]&0xf0 == 0x40 {
|
|
||||||
// IPv4 packet found
|
|
||||||
if len(b) < 20 {
|
|
||||||
// Packet was too short
|
|
||||||
util.PutBytes(b)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// Extract the IPv4 addresses
|
|
||||||
copy(srcAddr[:4], b[12:16])
|
|
||||||
copy(dstAddr[:4], b[16:20])
|
|
||||||
addrlen = 4
|
|
||||||
} else {
|
|
||||||
// Neither IPv4 nor IPv6
|
|
||||||
return errors.New("Invalid address family")
|
|
||||||
}
|
|
||||||
// Check the crypto-key routing rules next
|
|
||||||
if tun.ckr.isEnabled() {
|
|
||||||
if !tun.ckr.isValidLocalAddress(dstAddr, addrlen) {
|
|
||||||
util.PutBytes(b)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if srcAddr[0] != 0x02 && srcAddr[0] != 0x03 {
|
|
||||||
// TODO: is this check useful? this doesn't actually guarantee that the
|
|
||||||
// packet came from the configured public key for that remote, just that
|
|
||||||
// it came from *a* configured remote. at this stage we have no ability
|
|
||||||
// to know which Conn or public key was involved
|
|
||||||
if _, err := tun.ckr.getPublicKeyForAddress(srcAddr, addrlen); err != nil {
|
|
||||||
util.PutBytes(b)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if addrlen != 16 {
|
|
||||||
util.PutBytes(b)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if !bytes.Equal(tun.addr[:16], dstAddr[:16]) && !bytes.Equal(tun.subnet[:8], dstAddr[:8]) {
|
|
||||||
util.PutBytes(b)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if tun.iface.IsTAP() {
|
if tun.iface.IsTAP() {
|
||||||
sendndp := func(dstAddr address.Address) {
|
sendndp := func(dstAddr address.Address) {
|
||||||
neigh, known := tun.icmpv6.getNeighbor(dstAddr)
|
neigh, known := tun.icmpv6.getNeighbor(dstAddr)
|
||||||
@ -86,6 +29,7 @@ func (tun *TunAdapter) writer() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
peermac := net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
peermac := net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
||||||
|
var dstAddr address.Address
|
||||||
var peerknown bool
|
var peerknown bool
|
||||||
if b[0]&0xf0 == 0x40 {
|
if b[0]&0xf0 == 0x40 {
|
||||||
dstAddr = tun.addr
|
dstAddr = tun.addr
|
||||||
@ -183,10 +127,7 @@ func (tun *TunAdapter) readerPacketHandler(ch chan []byte) {
|
|||||||
// From the IP header, work out what our source and destination addresses
|
// From the IP header, work out what our source and destination addresses
|
||||||
// and node IDs are. We will need these in order to work out where to send
|
// and node IDs are. We will need these in order to work out where to send
|
||||||
// the packet
|
// the packet
|
||||||
var srcAddr address.Address
|
|
||||||
var dstAddr address.Address
|
var dstAddr address.Address
|
||||||
var dstNodeID *crypto.NodeID
|
|
||||||
var dstNodeIDMask *crypto.NodeID
|
|
||||||
var dstSnet address.Subnet
|
var dstSnet address.Subnet
|
||||||
var addrlen int
|
var addrlen int
|
||||||
n := len(bs)
|
n := len(bs)
|
||||||
@ -203,7 +144,6 @@ func (tun *TunAdapter) readerPacketHandler(ch chan []byte) {
|
|||||||
}
|
}
|
||||||
// IPv6 address
|
// IPv6 address
|
||||||
addrlen = 16
|
addrlen = 16
|
||||||
copy(srcAddr[:addrlen], bs[8:])
|
|
||||||
copy(dstAddr[:addrlen], bs[24:])
|
copy(dstAddr[:addrlen], bs[24:])
|
||||||
copy(dstSnet[:addrlen/2], bs[24:])
|
copy(dstSnet[:addrlen/2], bs[24:])
|
||||||
} else if bs[0]&0xf0 == 0x40 {
|
} else if bs[0]&0xf0 == 0x40 {
|
||||||
@ -217,7 +157,6 @@ func (tun *TunAdapter) readerPacketHandler(ch chan []byte) {
|
|||||||
}
|
}
|
||||||
// IPv4 address
|
// IPv4 address
|
||||||
addrlen = 4
|
addrlen = 4
|
||||||
copy(srcAddr[:addrlen], bs[12:])
|
|
||||||
copy(dstAddr[:addrlen], bs[16:])
|
copy(dstAddr[:addrlen], bs[16:])
|
||||||
} else {
|
} else {
|
||||||
// Unknown address length or protocol, so drop the packet and ignore it
|
// Unknown address length or protocol, so drop the packet and ignore it
|
||||||
@ -225,36 +164,22 @@ func (tun *TunAdapter) readerPacketHandler(ch chan []byte) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if tun.ckr.isEnabled() {
|
if tun.ckr.isEnabled() {
|
||||||
if !tun.ckr.isValidLocalAddress(srcAddr, addrlen) {
|
if addrlen != 16 || (!dstAddr.IsValid() && !dstSnet.IsValid()) {
|
||||||
continue
|
|
||||||
}
|
|
||||||
if !dstAddr.IsValid() && !dstSnet.IsValid() {
|
|
||||||
if key, err := tun.ckr.getPublicKeyForAddress(dstAddr, addrlen); err == nil {
|
if key, err := tun.ckr.getPublicKeyForAddress(dstAddr, addrlen); err == nil {
|
||||||
// A public key was found, get the node ID for the search
|
// A public key was found, get the node ID for the search
|
||||||
dstNodeID = crypto.GetNodeID(&key)
|
dstNodeID := crypto.GetNodeID(&key)
|
||||||
// Do a quick check to ensure that the node ID refers to a vaild
|
dstAddr = *address.AddrForNodeID(dstNodeID)
|
||||||
// Yggdrasil address or subnet - this might be superfluous
|
dstSnet = *address.SubnetForNodeID(dstNodeID)
|
||||||
addr := *address.AddrForNodeID(dstNodeID)
|
addrlen = 16
|
||||||
copy(dstAddr[:], addr[:])
|
|
||||||
copy(dstSnet[:], addr[:])
|
|
||||||
// Are we certain we looked up a valid node?
|
|
||||||
if !dstAddr.IsValid() && !dstSnet.IsValid() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// No public key was found in the CKR table so we've exhausted our options
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if addrlen != 16 {
|
if addrlen != 16 || (!dstAddr.IsValid() && !dstSnet.IsValid()) {
|
||||||
continue
|
// Couldn't find this node's ygg IP
|
||||||
}
|
continue
|
||||||
if !dstAddr.IsValid() && !dstSnet.IsValid() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Do we have an active connection for this node address?
|
// Do we have an active connection for this node address?
|
||||||
|
var dstNodeID, dstNodeIDMask *crypto.NodeID
|
||||||
tun.mutex.RLock()
|
tun.mutex.RLock()
|
||||||
session, isIn := tun.addrToConn[dstAddr]
|
session, isIn := tun.addrToConn[dstAddr]
|
||||||
if !isIn || session == nil {
|
if !isIn || session == nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user