Example #1
0
    def IncomingConnection(self, version, end_state, netid):
        self.s = self.OpenListenSocket(version, netid)
        self.end_state = end_state

        remoteaddr = self.remoteaddr = self.GetRemoteAddress(version)
        remotesockaddr = self.remotesockaddr = self.GetRemoteSocketAddress(
            version)

        myaddr = self.myaddr = self.MyAddress(version, netid)
        mysockaddr = self.mysockaddr = self.MySocketAddress(version, netid)

        if version == 5: version = 4
        self.version = version

        if end_state == TCP_LISTEN:
            return

        desc, syn = packets.SYN(self.port, version, remoteaddr, myaddr)
        synack_desc, synack = packets.SYNACK(version, myaddr, remoteaddr, syn)
        msg = "Received %s, expected to see reply %s" % (desc, synack_desc)
        reply = self._ReceiveAndExpectResponse(netid, syn, synack, msg)
        if end_state == TCP_SYN_RECV:
            return

        establishing_ack = packets.ACK(version, remoteaddr, myaddr, reply)[1]
        self.ReceivePacketOn(netid, establishing_ack)

        if end_state == TCP_NOT_YET_ACCEPTED:
            return

        self.accepted, _ = self.s.accept()
        net_test.DisableFinWait(self.accepted)

        if end_state == TCP_ESTABLISHED:
            return

        desc, data = packets.ACK(version,
                                 myaddr,
                                 remoteaddr,
                                 establishing_ack,
                                 payload=net_test.UDP_PAYLOAD)
        self.accepted.send(net_test.UDP_PAYLOAD)
        self.ExpectPacketOn(netid, msg + ": expecting %s" % desc, data)

        desc, fin = packets.FIN(version, remoteaddr, myaddr, data)
        fin = packets._GetIpLayer(version)(str(fin))
        ack_desc, ack = packets.ACK(version, myaddr, remoteaddr, fin)
        msg = "Received %s, expected to see reply %s" % (desc, ack_desc)

        # TODO: Why can't we use this?
        #   self._ReceiveAndExpectResponse(netid, fin, ack, msg)
        self.ReceivePacketOn(netid, fin)
        time.sleep(0.1)
        self.ExpectPacketOn(netid, msg + ": expecting %s" % ack_desc, ack)
        if end_state == TCP_CLOSE_WAIT:
            return

        raise ValueError("Invalid TCP state %d specified" % end_state)
Example #2
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
Example #3
0
 def TFOClientSocket(self, version, netid):
     s = net_test.TCPSocket(net_test.GetAddressFamily(version))
     net_test.DisableFinWait(s)
     self.SelectInterface(s, netid, "mark")
     s.setsockopt(IPPROTO_TCP, TCP_FASTOPEN_CONNECT, 1)
     return s