예제 #1
0
파일: xfrm_test.py 프로젝트: fukehan/kernel
    def _CheckNullEncryptionTunnelMode(self, version):
        family = net_test.GetAddressFamily(version)
        netid = self.RandomNetid()
        local_addr = self.MyAddress(version, netid)
        remote_addr = self.GetRemoteAddress(version)

        # Borrow the address of another netId as the source address of the tunnel
        tun_local = self.MyAddress(version, self.RandomNetid(netid))
        # For generality, pick a tunnel endpoint that's not the address we
        # connect the socket to.
        tun_remote = TUNNEL_ENDPOINTS[version]

        # Output
        self.xfrm.AddSaInfo(tun_local, tun_remote, 0xABCD,
                            xfrm.XFRM_MODE_TUNNEL, 123,
                            xfrm_base._ALGO_CRYPT_NULL,
                            xfrm_base._ALGO_AUTH_NULL, None, None, None, netid)
        # Input
        self.xfrm.AddSaInfo(tun_remote, tun_local, 0x9876,
                            xfrm.XFRM_MODE_TUNNEL, 456,
                            xfrm_base._ALGO_CRYPT_NULL,
                            xfrm_base._ALGO_AUTH_NULL, None, None, None, None)

        sock = net_test.UDPSocket(family)
        self.SelectInterface(sock, netid, "mark")
        sock.bind((local_addr, 0))
        local_port = sock.getsockname()[1]
        remote_port = 5555

        xfrm_base.ApplySocketPolicy(sock, family, xfrm.XFRM_POLICY_OUT, 0xABCD,
                                    123, (tun_local, tun_remote))
        xfrm_base.ApplySocketPolicy(sock, family, xfrm.XFRM_POLICY_IN, 0x9876,
                                    456, (tun_remote, tun_local))

        # Create and receive an ESP packet.
        IpType = {4: scapy.IP, 6: scapy.IPv6}[version]
        input_pkt = (IpType(src=remote_addr, dst=local_addr) /
                     scapy.UDP(sport=remote_port, dport=local_port) /
                     "input hello")
        input_pkt = IpType(str(input_pkt))  # Compute length, checksum.
        input_pkt = xfrm_base.EncryptPacketWithNull(input_pkt, 0x9876, 1,
                                                    (tun_remote, tun_local))

        self.ReceivePacketOn(netid, input_pkt)
        msg, addr = sock.recvfrom(1024)
        self.assertEquals("input hello", msg)
        self.assertEquals((remote_addr, remote_port), addr[:2])

        # Send and capture a packet.
        sock.sendto("output hello", (remote_addr, remote_port))
        packets = self.ReadAllPacketsOn(netid)
        self.assertEquals(1, len(packets))
        output_pkt = packets[0]
        output_pkt, esp_hdr = xfrm_base.DecryptPacketWithNull(output_pkt)
        self.assertEquals(output_pkt[scapy.UDP].len, len("output_hello") + 8)
        self.assertEquals(remote_addr, output_pkt.dst)
        self.assertEquals(remote_port, output_pkt[scapy.UDP].dport)
        # length of the payload plus the UDP header
        self.assertEquals("output hello", str(output_pkt[scapy.UDP].payload))
        self.assertEquals(0xABCD, esp_hdr.spi)
예제 #2
0
파일: xfrm_test.py 프로젝트: fukehan/kernel
    def _SetupUdpEncapSaPair(self, myaddr, remoteaddr, in_spi, out_spi,
                             encap_port, s, use_null_auth):
        in_reqid = 123
        out_reqid = 456

        # Create inbound and outbound SAs that specify UDP encapsulation.
        encaptmpl = xfrm.XfrmEncapTmpl(
            (xfrm.UDP_ENCAP_ESPINUDP, htons(encap_port), htons(4500),
             16 * "\x00"))
        self.CreateNewSa(myaddr, remoteaddr, out_spi, out_reqid, encaptmpl,
                         use_null_auth)

        # Add an encap template that's the mirror of the outbound one.
        encaptmpl.sport, encaptmpl.dport = encaptmpl.dport, encaptmpl.sport
        self.CreateNewSa(remoteaddr, myaddr, in_spi, in_reqid, encaptmpl,
                         use_null_auth)

        # Apply socket policies to s.
        xfrm_base.ApplySocketPolicy(s, AF_INET, xfrm.XFRM_POLICY_OUT, out_spi,
                                    out_reqid, None)

        # TODO: why does this work without a per-socket policy applied?
        # The received  packet obviously matches an SA, but don't inbound packets
        # need to match a policy as well? (b/71541609)
        xfrm_base.ApplySocketPolicy(s, AF_INET, xfrm.XFRM_POLICY_IN, in_spi,
                                    in_reqid, None)
예제 #3
0
파일: xfrm_test.py 프로젝트: fukehan/kernel
    def _TestSocketPolicyDstCache(self, version):
        """Test that destination cache is cleared with socket policy.

    This relies on the fact that connect() on a UDP socket populates the
    destination cache.
    """

        # Create UDP socket.
        family = net_test.GetAddressFamily(version)
        netid = self.RandomNetid()
        s = socket(family, SOCK_DGRAM, 0)
        self.SelectInterface(s, netid, "mark")

        # Populate the socket's destination cache.
        remote = self.GetRemoteAddress(version)
        s.connect((remote, 53))

        # Apply a policy to the socket. Should clear dst cache.
        reqid = 123
        xfrm_base.ApplySocketPolicy(s, family, xfrm.XFRM_POLICY_OUT, TEST_SPI,
                                    reqid, None)

        # Policy with no matching SA should result in EAGAIN. If destination cache
        # failed to clear, then the UDP packet will be sent normally.
        with self.assertRaisesErrno(EAGAIN):
            s.send(net_test.UDP_PAYLOAD)
        self.ExpectNoPacketsOn(netid, "Packet not blocked by policy")
예제 #4
0
파일: xfrm_test.py 프로젝트: fukehan/kernel
    def _CheckTunnelModeOutputMark(self, version, tunsrc, mark,
                                   expected_netid):
        """Tests sending UDP packets to tunnel mode SAs with output marks.

    Opens a UDP socket and binds it to a random netid, then sets up tunnel mode
    SAs with an output_mark of mark and sets a socket policy to use the SA.
    Then checks that sending on those SAs sends a packet on expected_netid,
    or, if expected_netid is zero, checks that sending returns ENETUNREACH.

    Args:
      version: 4 or 6.
      tunsrc: A string, the source address of the tunnel.
      mark: An integer, the output_mark to set in the SA.
      expected_netid: An integer, the netid to expect the kernel to send the
          packet on. If None, expect that sendto will fail with ENETUNREACH.
    """
        # Open a UDP socket and bind it to a random netid.
        family = net_test.GetAddressFamily(version)
        s = socket(family, SOCK_DGRAM, 0)
        self.SelectInterface(s, self.RandomNetid(), "mark")

        # For generality, pick a tunnel endpoint that's not the address we
        # connect the socket to.
        tundst = TUNNEL_ENDPOINTS[version]
        tun_addrs = (tunsrc, tundst)

        # Create a tunnel mode SA and use XFRM_OUTPUT_MARK to bind it to netid.
        spi = TEST_SPI * mark
        reqid = 100 + spi
        self.xfrm.AddSaInfo(tunsrc, tundst, spi, xfrm.XFRM_MODE_TUNNEL, reqid,
                            xfrm_base._ALGO_CBC_AES_256,
                            xfrm_base._ALGO_HMAC_SHA1, None, None, None, mark)

        # Set a socket policy to use it.
        xfrm_base.ApplySocketPolicy(s, family, xfrm.XFRM_POLICY_OUT, spi,
                                    reqid, tun_addrs)

        # Send a packet and check that we see it on the wire.
        remoteaddr = self.GetRemoteAddress(version)

        packetlen = xfrm_base.GetEspPacketLength(xfrm.XFRM_MODE_TUNNEL,
                                                 version, False,
                                                 net_test.UDP_PAYLOAD,
                                                 xfrm_base._ALGO_HMAC_SHA1,
                                                 xfrm_base._ALGO_CBC_AES_256)

        if expected_netid is not None:
            s.sendto(net_test.UDP_PAYLOAD, (remoteaddr, 53))
            self._ExpectEspPacketOn(expected_netid, spi, 1, packetlen, tunsrc,
                                    tundst)
        else:
            with self.assertRaisesErrno(ENETUNREACH):
                s.sendto(net_test.UDP_PAYLOAD, (remoteaddr, 53))
예제 #5
0
    def ParamTestSocketPolicySimple(self, params):
        """Test two-way traffic using transport mode and socket policies."""
        def AssertEncrypted(packet):
            # This gives a free pass to ICMP and ICMPv6 packets, which show up
            # nondeterministically in tests.
            self.assertEquals(None, packet.getlayer(scapy.UDP),
                              "UDP packet sent in the clear")
            self.assertEquals(None, packet.getlayer(scapy.TCP),
                              "TCP packet sent in the clear")

        # We create a pair of sockets, "left" and "right", that will talk to each
        # other using transport mode ESP. Because of TapTwister, both sockets
        # perceive each other as owning "remote_addr".
        netid = self.RandomNetid()
        family = net_test.GetAddressFamily(params["version"])
        local_addr = self.MyAddress(params["version"], netid)
        remote_addr = self.GetRemoteSocketAddress(params["version"])
        crypt_left = (xfrm.XfrmAlgo(
            (params["crypt"].name, params["crypt"].key_len)),
                      os.urandom(params["crypt"].key_len /
                                 8)) if params["crypt"] else None
        crypt_right = (xfrm.XfrmAlgo(
            (params["crypt"].name, params["crypt"].key_len)),
                       os.urandom(params["crypt"].key_len /
                                  8)) if params["crypt"] else None
        auth_left = (xfrm.XfrmAlgoAuth(
            (params["auth"].name,
             params["auth"].key_len, params["auth"].trunc_len)),
                     os.urandom(params["auth"].key_len /
                                8)) if params["auth"] else None
        auth_right = (xfrm.XfrmAlgoAuth(
            (params["auth"].name,
             params["auth"].key_len, params["auth"].trunc_len)),
                      os.urandom(params["auth"].key_len /
                                 8)) if params["auth"] else None
        aead_left = (xfrm.XfrmAlgoAead(
            (params["aead"].name,
             params["aead"].key_len, params["aead"].icv_len)),
                     os.urandom(params["aead"].key_len /
                                8)) if params["aead"] else None
        aead_right = (xfrm.XfrmAlgoAead(
            (params["aead"].name,
             params["aead"].key_len, params["aead"].icv_len)),
                      os.urandom(params["aead"].key_len /
                                 8)) if params["aead"] else None
        spi_left = 0xbeefface
        spi_right = 0xcafed00d
        req_ids = [100, 200, 300, 400]  # Used to match templates and SAs.

        # Left outbound SA
        self.xfrm.AddSaInfo(src=local_addr,
                            dst=remote_addr,
                            spi=spi_right,
                            mode=xfrm.XFRM_MODE_TRANSPORT,
                            reqid=req_ids[0],
                            encryption=crypt_right,
                            auth_trunc=auth_right,
                            aead=aead_right,
                            encap=None,
                            mark=None,
                            output_mark=None)
        # Right inbound SA
        self.xfrm.AddSaInfo(src=remote_addr,
                            dst=local_addr,
                            spi=spi_right,
                            mode=xfrm.XFRM_MODE_TRANSPORT,
                            reqid=req_ids[1],
                            encryption=crypt_right,
                            auth_trunc=auth_right,
                            aead=aead_right,
                            encap=None,
                            mark=None,
                            output_mark=None)
        # Right outbound SA
        self.xfrm.AddSaInfo(src=local_addr,
                            dst=remote_addr,
                            spi=spi_left,
                            mode=xfrm.XFRM_MODE_TRANSPORT,
                            reqid=req_ids[2],
                            encryption=crypt_left,
                            auth_trunc=auth_left,
                            aead=aead_left,
                            encap=None,
                            mark=None,
                            output_mark=None)
        # Left inbound SA
        self.xfrm.AddSaInfo(src=remote_addr,
                            dst=local_addr,
                            spi=spi_left,
                            mode=xfrm.XFRM_MODE_TRANSPORT,
                            reqid=req_ids[3],
                            encryption=crypt_left,
                            auth_trunc=auth_left,
                            aead=aead_left,
                            encap=None,
                            mark=None,
                            output_mark=None)

        # Make two sockets.
        sock_left = socket(family, params["proto"], 0)
        sock_left.settimeout(2.0)
        sock_left.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        self.SelectInterface(sock_left, netid, "mark")
        sock_right = socket(family, params["proto"], 0)
        sock_right.settimeout(2.0)
        sock_right.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        self.SelectInterface(sock_right, netid, "mark")

        # For UDP, set SO_LINGER to 0, to prevent TCP sockets from hanging around
        # in a TIME_WAIT state.
        if params["proto"] == SOCK_STREAM:
            net_test.DisableFinWait(sock_left)
            net_test.DisableFinWait(sock_right)

        # Apply the left outbound socket policy.
        xfrm_base.ApplySocketPolicy(sock_left, family, xfrm.XFRM_POLICY_OUT,
                                    spi_right, req_ids[0], None)
        # Apply right inbound socket policy.
        xfrm_base.ApplySocketPolicy(sock_right, family, xfrm.XFRM_POLICY_IN,
                                    spi_right, req_ids[1], None)
        # Apply right outbound socket policy.
        xfrm_base.ApplySocketPolicy(sock_right, family, xfrm.XFRM_POLICY_OUT,
                                    spi_left, req_ids[2], None)
        # Apply left inbound socket policy.
        xfrm_base.ApplySocketPolicy(sock_left, family, xfrm.XFRM_POLICY_IN,
                                    spi_left, req_ids[3], None)

        server_ready = threading.Event()
        server_error = None  # Save exceptions thrown by the server.

        def TcpServer(sock, client_port):
            try:
                sock.listen(1)
                server_ready.set()
                accepted, peer = sock.accept()
                self.assertEquals(remote_addr, peer[0])
                self.assertEquals(client_port, peer[1])
                data = accepted.recv(2048)
                self.assertEquals("hello request", data)
                accepted.send("hello response")
            except Exception as e:
                server_error = e
            finally:
                sock.close()

        def UdpServer(sock, client_port):
            try:
                server_ready.set()
                data, peer = sock.recvfrom(2048)
                self.assertEquals(remote_addr, peer[0])
                self.assertEquals(client_port, peer[1])
                self.assertEquals("hello request", data)
                sock.sendto("hello response", peer)
            except Exception as e:
                server_error = e
            finally:
                sock.close()

        # Server and client need to know each other's port numbers in advance.
        wildcard_addr = net_test.GetWildcardAddress(params["version"])
        sock_left.bind((wildcard_addr, 0))
        sock_right.bind((wildcard_addr, 0))
        left_port = sock_left.getsockname()[1]
        right_port = sock_right.getsockname()[1]

        # Start the appropriate server type on sock_right.
        target = TcpServer if params["proto"] == SOCK_STREAM else UdpServer
        server = threading.Thread(target=target,
                                  args=(sock_right, left_port),
                                  name="SocketServer")
        server.start()
        # Wait for server to be ready before attempting to connect. TCP retries
        # hide this problem, but UDP will fail outright if the server socket has
        # not bound when we send.
        self.assertTrue(server_ready.wait(2.0),
                        "Timed out waiting for server thread")

        with TapTwister(fd=self.tuns[netid].fileno(),
                        validator=AssertEncrypted):
            sock_left.connect((remote_addr, right_port))
            sock_left.send("hello request")
            data = sock_left.recv(2048)
            self.assertEquals("hello response", data)
            sock_left.close()
            server.join()
        if server_error:
            raise server_error
예제 #6
0
파일: xfrm_test.py 프로젝트: fukehan/kernel
    def _TestSocketPolicy(self, version):
        # Open a UDP socket and connect it.
        family = net_test.GetAddressFamily(version)
        s = socket(family, SOCK_DGRAM, 0)
        netid = self.RandomNetid()
        self.SelectInterface(s, netid, "mark")

        remotesockaddr = self.GetRemoteSocketAddress(version)
        s.connect((remotesockaddr, 53))
        saddr, sport = s.getsockname()[:2]
        daddr, dport = s.getpeername()[:2]
        if version == 5:
            saddr = saddr.replace("::ffff:", "")
            daddr = daddr.replace("::ffff:", "")

        reqid = 0

        desc, pkt = packets.UDP(version, saddr, daddr, sport=sport)
        s.sendto(net_test.UDP_PAYLOAD, (remotesockaddr, 53))
        self.ExpectPacketOn(netid, "Send after socket, expected %s" % desc,
                            pkt)

        # Using IPv4 XFRM on a dual-stack socket requires setting an AF_INET policy
        # that's written in terms of IPv4 addresses.
        xfrm_version = 4 if version == 5 else version
        xfrm_family = net_test.GetAddressFamily(xfrm_version)
        xfrm_base.ApplySocketPolicy(s, xfrm_family, xfrm.XFRM_POLICY_OUT,
                                    TEST_SPI, reqid, None)

        # Because the policy has level set to "require" (the default), attempting
        # to send a packet results in an error, because there is no SA that
        # matches the socket policy we set.
        self.assertRaisesErrno(EAGAIN, s.sendto, net_test.UDP_PAYLOAD,
                               (remotesockaddr, 53))

        # Adding a matching SA causes the packet to go out encrypted. The SA's
        # SPI must match the one in our template, and the destination address must
        # match the packet's destination address (in tunnel mode, it has to match
        # the tunnel destination).
        self.CreateNewSa(net_test.GetWildcardAddress(xfrm_version),
                         self.GetRemoteAddress(xfrm_version), TEST_SPI, reqid,
                         None)
        s.sendto(net_test.UDP_PAYLOAD, (remotesockaddr, 53))
        expected_length = xfrm_base.GetEspPacketLength(
            xfrm.XFRM_MODE_TRANSPORT, version, False, net_test.UDP_PAYLOAD,
            xfrm_base._ALGO_HMAC_SHA1, xfrm_base._ALGO_CBC_AES_256)
        self._ExpectEspPacketOn(netid, TEST_SPI, 1, expected_length, None,
                                None)

        # Sending to another destination doesn't work: again, no matching SA.
        remoteaddr2 = self.GetOtherRemoteSocketAddress(version)
        self.assertRaisesErrno(EAGAIN, s.sendto, net_test.UDP_PAYLOAD,
                               (remoteaddr2, 53))

        # Sending on another socket without the policy applied results in an
        # unencrypted packet going out.
        s2 = socket(family, SOCK_DGRAM, 0)
        self.SelectInterface(s2, netid, "mark")
        s2.sendto(net_test.UDP_PAYLOAD, (remotesockaddr, 53))
        pkts = self.ReadAllPacketsOn(netid)
        self.assertEquals(1, len(pkts))
        packet = pkts[0]

        protocol = packet.nh if version == 6 else packet.proto
        self.assertEquals(IPPROTO_UDP, protocol)

        # Deleting the SA causes the first socket to return errors again.
        self.xfrm.DeleteSaInfo(self.GetRemoteAddress(xfrm_version), TEST_SPI,
                               IPPROTO_ESP)
        self.assertRaisesErrno(EAGAIN, s.sendto, net_test.UDP_PAYLOAD,
                               (remotesockaddr, 53))

        # Clear the socket policy and expect a cleartext packet.
        xfrm_base.SetPolicySockopt(s, family, None)
        s.sendto(net_test.UDP_PAYLOAD, (remotesockaddr, 53))
        self.ExpectPacketOn(netid, "Send after clear, expected %s" % desc, pkt)

        # Clearing the policy twice is safe.
        xfrm_base.SetPolicySockopt(s, family, None)
        s.sendto(net_test.UDP_PAYLOAD, (remotesockaddr, 53))
        self.ExpectPacketOn(netid, "Send after clear 2, expected %s" % desc,
                            pkt)

        # Clearing if a policy was never set is safe.
        s = socket(AF_INET6, SOCK_DGRAM, 0)
        xfrm_base.SetPolicySockopt(s, family, None)