Beispiel #1
0
 def __init__(self, shared_=None, log_fn=print):
     self.callout = win32file.CreateFile(
         self.CALLOUT_DRIVER_NAME,
         win32file.GENERIC_READ | win32file.GENERIC_WRITE,
         win32file.FILE_SHARE_READ, None, win32file.OPEN_EXISTING, 0, 0)
     self.log = log_fn
     if shared_ is None:
         self.shared = RAVerifier(self.log)
     else:
         self.shared = shared_
Beispiel #2
0
    def __init__(self, config=None, socket_=None, verifier=None):
        if socket_ is None:
            self.socket = socket.socket(socket.PF_SYSTEM, socket.SOCK_STREAM,
                                        socket.SYSPROTO_CONTROL)
        else:
            self.socket = socket_

        if verifier is None:
            syslog.openlog("TrustRouter")

            def log(string):
                syslog.syslog(syslog.LOG_ALERT, string)

            self.verifier = RAVerifier(log, config)
        else:
            self.verifier = verifier
Beispiel #3
0
def cb(payload):
    print("python callback called!")

    common_part = RAVerifier()
    sock = socket.socket(
        socket.AF_INET6,
        socket.SOCK_RAW,
        IPPROTO_ICMPV6)        
    sock.settimeout(2)
    if common_part.verify(
            payload.get_data(),
            payload.get_indev(),
            sock):
        payload.set_verdict(nfqueue.NF_ACCEPT)
    else:
        payload.set_verdict(nfqueue.NF_DROP)

    sys.stdout.flush()
    return 1
Beispiel #4
0
class TestMac(unittest.TestCase):

    RA_PACKET = b"\x60\x00\x00\x00\x01\xc8\x3a\xff\xfe\x80\x00\x00\x00\x00\x00\x00\x2c\xf2\x7e\xf7\x8f\x98\xdf\x97\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x86\x00\x46\xa8\x40\x00\x00\xb4\x00\x00\x00\x00\x00\x00\x00\x00\x03\x04\x40\xe0\x00\x01\x51\x80\x00\x00\x38\x40\x00\x00\x00\x00\x20\x01\x06\x38\x08\x07\x02\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x19\x03\x00\x00\x00\x00\x00\x3c\x20\x01\x06\x38\x08\x07\x02\x01\x02\x11\x43\xff\xfe\x5b\x35\x1b\x01\x01\x00\x00\x1c\xd5\x06\x41\x0b\x18\x01\x00\x40\x7e\xd5\xfc\xc9\x69\x05\x3d\x8f\xa3\x7b\xb6\x09\x39\x86\xe2\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x30\x81\x9f\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x81\x8d\x00\x30\x81\x89\x02\x81\x81\x00\xaf\x96\x81\x88\xe2\xfb\x44\x20\x3d\xa9\xc9\x1b\x07\xde\x9d\x55\x27\x9e\xf7\xdc\xe6\xe2\xd2\x9b\x5c\x9a\x46\x72\x2b\x02\x10\xce\x4d\xc2\x87\xb7\x74\x03\x91\xac\xcd\xc5\x87\x5e\x06\xaf\xc8\x9a\xda\x29\xf9\xe9\x16\x8a\xc6\x97\x62\x76\xbb\x14\xb0\xab\xb7\xfe\x03\x34\x12\x98\x4b\x8e\x77\xba\x2b\x1b\x09\x8f\x6e\xd9\xb3\x59\x68\xb5\x35\xa8\x68\x08\x21\x70\x7f\x65\x6d\xca\xd1\x75\xdd\xc1\xbc\x1c\xc6\xee\x8b\x8c\x74\x3f\xbd\x8b\x8f\xde\x26\xa1\x99\x3b\xb2\x3c\xb6\x6b\xfc\xc5\xa1\x76\xaf\xd5\x07\x02\x62\x71\x6c\x09\x02\x03\x01\x00\x01\x00\x0d\x02\x00\x00\x00\x00\x00\x00\x00\x00\x4f\x17\xed\xe3\x79\xae\x2a\x02\x07\x00\x80\x81\x0a\x0b\x09\x00\x00\x00\x00\x00\x00\x00\x0c\x13\x00\x00\xf8\x55\x0b\xb2\x49\xe1\xd9\x0a\x2a\xe4\x00\xc2\x02\xc1\x8b\xff\x28\xcb\x82\x44\x51\x3c\x43\xd9\x54\xa3\xa3\x88\x03\xc5\x12\xf3\x00\x1f\x8c\x07\x55\x5b\x26\x35\xd6\xfb\x8b\x61\x69\xf2\x28\xb9\x33\x41\xa0\x01\xbb\x71\x37\x03\x02\x52\xb0\xe6\x54\x51\x0c\x50\x2b\xc0\x2a\x49\x11\x1f\x32\x0f\xfe\x0a\x53\x08\xf5\xf9\x10\x2d\x46\x86\x3d\x95\x89\xe2\x24\xc5\x76\x60\x13\x0b\x33\x4a\x1b\xc4\x5d\xef\xa7\x9e\xbf\x7f\x88\x32\xdf\x08\xba\x5b\xac\x52\xa3\xe3\x5f\xc1\x5a\xf0\x36\xfa\x76\x56\x4d\x7e\x80\x72\x39\xd0\x4c\x5f\xca\x24\x06\xa6\x12\x8f\x94\x2f\xe1\x67\xc4\xe6\xc3\xba\x4a\x03\x00\x00\x00\x00"

    def setUp(self):
        self.verifier = RAVerifier()


    def test_checksum(self):
        checksum = self.verifier._checksum(self.RA_PACKET)
        self.assertEqual(checksum, b'\x65\x3a')
Beispiel #5
0
 def __init__(self, shared_=None, log_fn=print):
     self.callout = win32file.CreateFile(
         self.CALLOUT_DRIVER_NAME,
         win32file.GENERIC_READ | win32file.GENERIC_WRITE,
         win32file.FILE_SHARE_READ,
         None,
         win32file.OPEN_EXISTING,
         0,
         0)
     self.log = log_fn
     if shared_ is None:
         self.shared = RAVerifier(self.log)
     else:
         self.shared = shared_
Beispiel #6
0
 def __init__(self, config=None, socket_=None, verifier=None):
     if socket_ is None:
         self.socket = socket.socket(socket.PF_SYSTEM,
                                     socket.SOCK_STREAM,
                                     socket.SYSPROTO_CONTROL)
     else:
         self.socket = socket_
     
     if verifier is None:
         syslog.openlog("TrustRouter")
         def log(string):
             syslog.syslog(syslog.LOG_ALERT, string)
         self.verifier = RAVerifier(log, config)
     else:
         self.verifier = verifier
Beispiel #7
0
 def setUp(self):
     self.verifier = RAVerifier()
Beispiel #8
0
class MacOSAdapter(object):

    KEXT_NAME = "net.trustrouter.kext"

    ACTION_REJECT = 1
    ACTION_ACCEPT = 0
    
    def __init__(self, config=None, socket_=None, verifier=None):
        if socket_ is None:
            self.socket = socket.socket(socket.PF_SYSTEM,
                                        socket.SOCK_STREAM,
                                        socket.SYSPROTO_CONTROL)
        else:
            self.socket = socket_
        
        if verifier is None:
            syslog.openlog("TrustRouter")
            def log(string):
                syslog.syslog(syslog.LOG_ALERT, string)
            self.verifier = RAVerifier(log, config)
        else:
            self.verifier = verifier
        

    def main(self):
        self.socket.connect(self.KEXT_NAME)
        while True:
            packet_id = self._readBytes(struct.calcsize("P"))
            # Read IPv6 Header (= 40 bytes)
            packet = self._readBytes(40)
            scopeid = self._remove_scope_id_from_addrs(packet)
            # Unmarshal payload length field
            payload_length = struct.unpack("!H", packet[4:6])[0]
            packet.extend(self._readBytes(payload_length))

            sock = socket.socket(
                socket.AF_INET6,
                socket.SOCK_RAW,
                IPPROTO_ICMPV6)        
            sock.settimeout(2)
            
            try:
                verified_ra = self.verifier.verify(packet, scopeid, sock)
            except Exception as e:
                self.verifier.log("Error: %s" % e)
                # something went wrong during verification
                verified_ra = False

            sock.close()
            
            if verified_ra:
                self._send_result(packet_id, self.ACTION_ACCEPT)
            else:
                self._send_result(packet_id, self.ACTION_REJECT)


    def _send_result(self, id, action):
        result = bytearray(id)
        result.extend(struct.pack("P", action))
        self.socket.send(result)


    def _readBytes(self, count):
        result = bytearray()
        while len(result) != count:
            result.extend(self.socket.recv(count - len(result)))
        return result


    def _remove_scope_id_from_addrs(self, ipv6header):
        scopeid = 0
        if self._is_link_local(ipv6header[8:10]):
            scopeid = struct.unpack("!H", ipv6header[10:12])[0]
            ipv6header[10:12] = b"\x00\x00"
        if self._is_link_local(ipv6header[24:26]):
            scopeid = struct.unpack("!H", ipv6header[26:28])[0]
            ipv6header[26:28] = b"\x00\x00"
        return scopeid


    def _is_link_local(self, addr):
        return (addr[0] == 0xfe and addr[1] & 0xc0 == 0x80) or \
               (addr[0] == 0xff and (addr[1] & 0x0f == 0x02 or
                                     addr[1] & 0x0f == 0x01))
Beispiel #9
0
class WindowsAdapter(object):
    CALLOUT_DRIVER_NAME = "\\\\.\\trustrtr"
    POINTER_LENGTH = struct.calcsize("P")
    UNSIGNED_INTEGER_LENGTH = struct.calcsize("I")
    ACTION_BLOCK = "B"
    ACTION_PERMIT = "P"

    def __init__(self, shared_=None, log_fn=print):
        self.callout = win32file.CreateFile(
            self.CALLOUT_DRIVER_NAME,
            win32file.GENERIC_READ | win32file.GENERIC_WRITE,
            win32file.FILE_SHARE_READ, None, win32file.OPEN_EXISTING, 0, 0)
        self.log = log_fn
        if shared_ is None:
            self.shared = RAVerifier(self.log)
        else:
            self.shared = shared_

    def read_from_callout_until_success(self):
        result_code = 1
        while result_code != 0:
            try:
                result_code, result_buffer = win32file.ReadFile(
                    self.callout, 100000, None)
            except Exception:
                #print("Tried ReadFile, got nothing.")
                pass

            time.sleep(1)

        return result_buffer

    def main(self):
        result_buffer = self.read_from_callout_until_success()
        address_byte_array = bytearray(result_buffer[:self.POINTER_LENGTH])
        interface_index = bytearray(
            result_buffer[self.POINTER_LENGTH:self.POINTER_LENGTH +
                          self.UNSIGNED_INTEGER_LENGTH])
        packet_byte_array = bytearray(
            result_buffer[(self.POINTER_LENGTH +
                           self.UNSIGNED_INTEGER_LENGTH):])

        interface_index = struct.unpack("@I", interface_index)[0]

        #for packet_byte in packet_byte_array:
        #   print ("\\x%02x" % packet_byte, end="")

        result = bytearray()
        result.extend(address_byte_array)

        sock = socket.socket(socket.AF_INET6, socket.SOCK_RAW, IPPROTO_ICMPV6)
        sock.settimeout(2)
        ''' 
            The CPAs will have the solicited-node multicast address as target.
            Therefore, we need to join this multicast group.
            On Mac OS X, this seems to happen automatically.
        '''
        self.join_multicast_group(sock, interface_index)

        if self.shared.verify(packet_byte_array, interface_index, sock):
            action = self.ACTION_PERMIT
        else:
            action = self.ACTION_BLOCK

        sock.close()

        result.extend(struct.pack("c", bytes(action, encoding="ascii")))
        win32file.WriteFile(self.callout, result, None)

    def join_multicast_group(self, sock, interface_index):
        # Get all IPv6 address info tuples of the host.
        addr_info_list = [
            addr_info[4] for addr_info in socket.getaddrinfo(
                socket.gethostname(), None, family=socket.AF_INET6)
        ]

        # Filter IPv6 address infos by the specified interface index, select only IPv6 address
        addr_list = [
            addr[0] for addr in addr_info_list if addr[3] == interface_index
        ]

        for addr in addr_list:
            # Removes the %-sign if present and everything thereafter.
            addr = addr.partition("%")[0]

            # Get the byte representation of the address
            addr_bytes = IPv6Address(addr).packed

            # Build the solicited-node multicast address by appending the
            # last 3 bytes of the unicast address to ff02::1:ff__:
            mcast_addr_end = addr_bytes[-3:]
            mcast_addr = b"\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff" + mcast_addr_end
            mreq = struct.pack("=16sI", mcast_addr, interface_index)
            sock.setsockopt(IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, mreq)
Beispiel #10
0
class WindowsAdapter(object):
    CALLOUT_DRIVER_NAME = "\\\\.\\trustrtr"
    POINTER_LENGTH = struct.calcsize("P")
    UNSIGNED_INTEGER_LENGTH = struct.calcsize("I")
    ACTION_BLOCK = "B"
    ACTION_PERMIT = "P"

    def __init__(self, shared_=None, log_fn=print):
        self.callout = win32file.CreateFile(
            self.CALLOUT_DRIVER_NAME,
            win32file.GENERIC_READ | win32file.GENERIC_WRITE,
            win32file.FILE_SHARE_READ,
            None,
            win32file.OPEN_EXISTING,
            0,
            0)
        self.log = log_fn
        if shared_ is None:
            self.shared = RAVerifier(self.log)
        else:
            self.shared = shared_
    
    def read_from_callout_until_success(self):
        result_code = 1
        while result_code != 0:
            try:
                result_code, result_buffer = win32file.ReadFile(
                    self.callout,
                    100000,
                    None)
            except Exception:
                #print("Tried ReadFile, got nothing.")
                pass

            time.sleep(1)

        return result_buffer

    def main(self):        
        result_buffer = self.read_from_callout_until_success()
        address_byte_array = bytearray(result_buffer[:self.POINTER_LENGTH])
        interface_index = bytearray(result_buffer[self.POINTER_LENGTH:self.POINTER_LENGTH + self.UNSIGNED_INTEGER_LENGTH])
        packet_byte_array = bytearray(result_buffer[(self.POINTER_LENGTH + self.UNSIGNED_INTEGER_LENGTH):])

        interface_index = struct.unpack("@I", interface_index)[0]

        #for packet_byte in packet_byte_array:
        #   print ("\\x%02x" % packet_byte, end="")

        result = bytearray()
        result.extend(address_byte_array)

        sock = socket.socket(
            socket.AF_INET6,
            socket.SOCK_RAW,
            IPPROTO_ICMPV6)        
        sock.settimeout(2)
        
        ''' 
            The CPAs will have the solicited-node multicast address as target.
            Therefore, we need to join this multicast group.
            On Mac OS X, this seems to happen automatically.
        '''
        self.join_multicast_group(sock, interface_index)
        
        if self.shared.verify(packet_byte_array, interface_index, sock):                
            action = self.ACTION_PERMIT
        else:
            action = self.ACTION_BLOCK
            
        sock.close()
        
        result.extend(struct.pack("c", bytes(action, encoding="ascii")))
        win32file.WriteFile(self.callout, result, None)
        
    def join_multicast_group(self, sock, interface_index):
        # Get all IPv6 address info tuples of the host.
        addr_info_list = [addr_info[4] for addr_info in socket.getaddrinfo(socket.gethostname(), None, family=socket.AF_INET6)]
        
        # Filter IPv6 address infos by the specified interface index, select only IPv6 address
        addr_list = [addr[0] for addr in addr_info_list if addr[3] == interface_index]

        for addr in addr_list:        
            # Removes the %-sign if present and everything thereafter.
            addr = addr.partition("%")[0]

            # Get the byte representation of the address
            addr_bytes = IPv6Address(addr).packed

            # Build the solicited-node multicast address by appending the
            # last 3 bytes of the unicast address to ff02::1:ff__:
            mcast_addr_end = addr_bytes[-3:]            
            mcast_addr = b"\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff" + mcast_addr_end
            mreq = struct.pack("=16sI", mcast_addr, interface_index)
            sock.setsockopt(IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, mreq)
Beispiel #11
0
class MacOSAdapter(object):

    KEXT_NAME = "net.trustrouter.kext"

    ACTION_REJECT = 1
    ACTION_ACCEPT = 0

    def __init__(self, config=None, socket_=None, verifier=None):
        if socket_ is None:
            self.socket = socket.socket(socket.PF_SYSTEM, socket.SOCK_STREAM,
                                        socket.SYSPROTO_CONTROL)
        else:
            self.socket = socket_

        if verifier is None:
            syslog.openlog("TrustRouter")

            def log(string):
                syslog.syslog(syslog.LOG_ALERT, string)

            self.verifier = RAVerifier(log, config)
        else:
            self.verifier = verifier

    def main(self):
        self.socket.connect(self.KEXT_NAME)
        while True:
            packet_id = self._readBytes(struct.calcsize("P"))
            # Read IPv6 Header (= 40 bytes)
            packet = self._readBytes(40)
            scopeid = self._remove_scope_id_from_addrs(packet)
            # Unmarshal payload length field
            payload_length = struct.unpack("!H", packet[4:6])[0]
            packet.extend(self._readBytes(payload_length))

            sock = socket.socket(socket.AF_INET6, socket.SOCK_RAW,
                                 IPPROTO_ICMPV6)
            sock.settimeout(2)

            try:
                verified_ra = self.verifier.verify(packet, scopeid, sock)
            except Exception as e:
                self.verifier.log("Error: %s" % e)
                # something went wrong during verification
                verified_ra = False

            sock.close()

            if verified_ra:
                self._send_result(packet_id, self.ACTION_ACCEPT)
            else:
                self._send_result(packet_id, self.ACTION_REJECT)

    def _send_result(self, id, action):
        result = bytearray(id)
        result.extend(struct.pack("P", action))
        self.socket.send(result)

    def _readBytes(self, count):
        result = bytearray()
        while len(result) != count:
            result.extend(self.socket.recv(count - len(result)))
        return result

    def _remove_scope_id_from_addrs(self, ipv6header):
        scopeid = 0
        if self._is_link_local(ipv6header[8:10]):
            scopeid = struct.unpack("!H", ipv6header[10:12])[0]
            ipv6header[10:12] = b"\x00\x00"
        if self._is_link_local(ipv6header[24:26]):
            scopeid = struct.unpack("!H", ipv6header[26:28])[0]
            ipv6header[26:28] = b"\x00\x00"
        return scopeid

    def _is_link_local(self, addr):
        return (addr[0] == 0xfe and addr[1] & 0xc0 == 0x80) or \
               (addr[0] == 0xff and (addr[1] & 0x0f == 0x02 or
                                     addr[1] & 0x0f == 0x01))
Beispiel #12
0
from trustrouter.core import RAVerifier

packet = b"\x60\x00\x00\x00\x01\xc8\x3a\xff\xfe\x80\x00\x00\x00\x00\x00\x00\x2c\xf2\x7e\xf7\x8f\x98\xdf\x97\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x86\x00\x10\xf1\x40\x00\x00\xb4\x00\x00\x00\x00\x00\x00\x00\x00\x03\x04\x40\xe0\x00\x01\x51\x80\x00\x00\x38\x40\x00\x00\x00\x00\x20\x01\x06\x38\x08\x07\x02\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x19\x03\x00\x00\x00\x00\x00\x3c\x20\x01\x06\x38\x08\x07\x02\x01\x02\x11\x43\xff\xfe\x5b\x35\x1b\x01\x01\x00\x00\x1c\xd5\x06\x41\x0b\x18\x01\x00\x40\x7e\xd5\xfc\xc9\x69\x05\x3d\x8f\xa3\x7b\xb6\x09\x39\x86\xe2\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x30\x81\x9f\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x81\x8d\x00\x30\x81\x89\x02\x81\x81\x00\xaf\x96\x81\x88\xe2\xfb\x44\x20\x3d\xa9\xc9\x1b\x07\xde\x9d\x55\x27\x9e\xf7\xdc\xe6\xe2\xd2\x9b\x5c\x9a\x46\x72\x2b\x02\x10\xce\x4d\xc2\x87\xb7\x74\x03\x91\xac\xcd\xc5\x87\x5e\x06\xaf\xc8\x9a\xda\x29\xf9\xe9\x16\x8a\xc6\x97\x62\x76\xbb\x14\xb0\xab\xb7\xfe\x03\x34\x12\x98\x4b\x8e\x77\xba\x2b\x1b\x09\x8f\x6e\xd9\xb3\x59\x68\xb5\x35\xa8\x68\x08\x21\x70\x7f\x65\x6d\xca\xd1\x75\xdd\xc1\xbc\x1c\xc6\xee\x8b\x8c\x74\x3f\xbd\x8b\x8f\xde\x26\xa1\x99\x3b\xb2\x3c\xb6\x6b\xfc\xc5\xa1\x76\xaf\xd5\x07\x02\x62\x71\x6c\x09\x02\x03\x01\x00\x01\x00\x0d\x02\x00\x00\x00\x00\x00\x00\x00\x00\x4f\x1e\x90\x6e\xd0\x74\x2a\x02\x07\x00\x80\x81\x0a\x0b\x09\x00\x00\x00\x00\x00\x00\x00\x0c\x13\x00\x00\xf8\x55\x0b\xb2\x49\xe1\xd9\x0a\x2a\xe4\x00\xc2\x02\xc1\x8b\xff\x09\x24\x31\xdf\xb5\x66\xd2\x00\x74\x82\x0c\x84\x8d\xfa\x39\x33\x9c\x80\xfb\x7d\x2c\x10\x68\x7f\x4b\x75\x28\x28\x5a\x41\x39\x44\x23\x6f\x36\xc1\x42\x9a\x86\x3c\xcc\x25\xfc\xd7\x16\x66\x0a\x42\x46\xe5\x0b\x9f\x8f\x09\xf3\xde\x43\x58\xdc\x2b\xa7\x89\xbb\xa6\xf9\x98\x4b\xb2\x45\x28\x44\xd2\xd2\xa3\xaf\x85\x16\xf2\xca\x3f\x81\x7a\x99\xea\x7a\x39\xc8\xe5\xc1\xbc\x65\xf4\x5e\xa6\x88\x4b\x7a\x34\x55\x72\xd0\xbe\x2d\x51\xd2\xd9\x42\x2b\x68\x32\x77\x83\xc8\xbc\x6c\xf8\x79\x68\xcb\xed\x90\x84\x45\x20\xc5\x24\x60\xcf\x00\x00\x00\x00"

verifier = RAVerifier()

result = verifier.verify(packet, 4)

print(result)