def testIcmpSocketsNotInIcmp6(self): numrows = len(self.ReadProcNetSocket("icmp")) numrows6 = len(self.ReadProcNetSocket("icmp6")) s = net_test.Socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP) s.bind(("127.0.0.1", 0xace)) s.connect(("127.0.0.1", 0xbeef)) self.assertEquals(numrows + 1, len(self.ReadProcNetSocket("icmp"))) self.assertEquals(numrows6, len(self.ReadProcNetSocket("icmp6")))
def OpenListenSocket(self, version, netid): family = {4: AF_INET, 5: AF_INET6, 6: AF_INET6}[version] address = {4: "0.0.0.0", 5: "::", 6: "::"}[version] s = net_test.Socket(family, SOCK_STREAM, IPPROTO_TCP) # We haven't configured inbound iptables marking, so bind explicitly. self.SelectInterface(s, netid, "mark") self.port = net_test.BindRandomPort(version, s) return s
def OpenListenSocket(self, version, netid): self.port = packets.RandomPort() family = {4: AF_INET, 5: AF_INET6, 6: AF_INET6}[version] address = {4: "0.0.0.0", 5: "::", 6: "::"}[version] s = net_test.Socket(family, SOCK_STREAM, IPPROTO_TCP) s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) s.bind((address, self.port)) # We haven't configured inbound iptables marking, so bind explicitly. self.SelectInterface(s, netid, "mark") s.listen(100) return s
def testConnectInterrupted(self): """Tests that connect() is interrupted by SOCK_DESTROY.""" for version in [4, 5, 6]: family = {4: AF_INET, 5: AF_INET6, 6: AF_INET6}[version] s = net_test.Socket(family, SOCK_STREAM, IPPROTO_TCP) self.SelectInterface(s, self.netid, "mark") if version == 5: remoteaddr = "::ffff:" + self.GetRemoteAddress(4) version = 4 else: remoteaddr = self.GetRemoteAddress(version) s.bind(("", 0)) _, sport = s.getsockname()[:2] self.CloseDuringBlockingCall( s, lambda sock: sock.connect((remoteaddr, 53)), ECONNABORTED) desc, syn = packets.SYN(53, version, self.MyAddress(version, self.netid), remoteaddr, sport=sport, seq=None) self.ExpectPacketOn(self.netid, desc, syn) msg = "SOCK_DESTROY of socket in connect, expected no RST" self.ExpectNoPacketsOn(self.netid, msg)
def _SetupUdpEncapSockets(self): netid = self.RandomNetid() myaddr = self.MyAddress(4, netid) remoteaddr = self.GetRemoteAddress(4) # Reserve a port on which to receive UDP encapsulated packets. Sending # packets works without this (and potentially can send packets with a source # port belonging to another application), but receiving requires the port to # be bound and the encapsulation socket option enabled. encap_sock = net_test.Socket(AF_INET, SOCK_DGRAM, 0) encap_sock.bind((myaddr, 0)) encap_port = encap_sock.getsockname()[1] encap_sock.setsockopt(IPPROTO_UDP, xfrm.UDP_ENCAP, xfrm.UDP_ENCAP_ESPINUDP) # Open a socket to send traffic. s = socket(AF_INET, SOCK_DGRAM, 0) self.SelectInterface(s, netid, "mark") s.connect((remoteaddr, 53)) return netid, myaddr, remoteaddr, encap_sock, encap_port, s
def testUdpEncapWithSocketPolicy(self): # TODO: test IPv6 instead of IPv4. netid = random.choice(self.NETIDS) myaddr = self.MyAddress(4, netid) remoteaddr = self.GetRemoteAddress(4) # Reserve a port on which to receive UDP encapsulated packets. Sending # packets works without this (and potentially can send packets with a source # port belonging to another application), but receiving requires the port to # be bound and the encapsulation socket option enabled. encap_socket = net_test.Socket(AF_INET, SOCK_DGRAM, 0) encap_socket.bind((myaddr, 0)) encap_port = encap_socket.getsockname()[1] encap_socket.setsockopt(IPPROTO_UDP, xfrm.UDP_ENCAP, xfrm.UDP_ENCAP_ESPINUDP) # Open a socket to send traffic. s = socket(AF_INET, SOCK_DGRAM, 0) self.SelectInterface(s, netid, "mark") s.connect((remoteaddr, 53)) # Create a UDP encap policy and template inbound and outbound and apply # them to s. sel = xfrm.XfrmSelector((XFRM_ADDR_ANY, XFRM_ADDR_ANY, 0, 0, 0, 0, AF_INET, 0, 0, IPPROTO_UDP, 0, 0)) # Use the same SPI both inbound and outbound because this lets us receive # encrypted packets by simply replaying the packets the kernel sends. in_reqid = 123 in_spi = htonl(TEST_SPI) out_reqid = 456 out_spi = htonl(TEST_SPI) # Start with the outbound policy. # TODO: what happens without XFRM_SHARE_UNIQUE? info = xfrm.XfrmUserpolicyInfo( (sel, xfrm.NO_LIFETIME_CFG, xfrm.NO_LIFETIME_CUR, 100, 0, xfrm.XFRM_POLICY_OUT, xfrm.XFRM_POLICY_ALLOW, xfrm.XFRM_POLICY_LOCALOK, xfrm.XFRM_SHARE_UNIQUE)) xfrmid = xfrm.XfrmId((XFRM_ADDR_ANY, out_spi, IPPROTO_ESP)) usertmpl = xfrm.XfrmUserTmpl(( xfrmid, AF_INET, XFRM_ADDR_ANY, out_reqid, xfrm.XFRM_MODE_TRANSPORT, xfrm.XFRM_SHARE_UNIQUE, 0, # require ALL_ALGORITHMS, # auth algos ALL_ALGORITHMS, # encryption algos ALL_ALGORITHMS)) # compression algos data = info.Pack() + usertmpl.Pack() s.setsockopt(IPPROTO_IP, xfrm.IP_XFRM_POLICY, data) # Uncomment for debugging. # subprocess.call("ip xfrm policy".split()) # Create inbound and outbound SAs that specify UDP encapsulation. encaptmpl = xfrm.XfrmEncapTmpl( (xfrm.UDP_ENCAP_ESPINUDP, htons(encap_port), htons(4500), 16 * "\x00")) self.xfrm.AddMinimalSaInfo(myaddr, remoteaddr, out_spi, IPPROTO_ESP, xfrm.XFRM_MODE_TRANSPORT, out_reqid, ALGO_CBC_AES_256, ENCRYPTION_KEY, ALGO_HMAC_SHA1, AUTH_TRUNC_KEY, encaptmpl) # Add an encap template that's the mirror of the outbound one. encaptmpl.sport, encaptmpl.dport = encaptmpl.dport, encaptmpl.sport self.xfrm.AddMinimalSaInfo(remoteaddr, myaddr, in_spi, IPPROTO_ESP, xfrm.XFRM_MODE_TRANSPORT, in_reqid, ALGO_CBC_AES_256, ENCRYPTION_KEY, ALGO_HMAC_SHA1, AUTH_TRUNC_KEY, encaptmpl) # Uncomment for debugging. # subprocess.call("ip xfrm state".split()) # Now send a packet. s.sendto("foo", (remoteaddr, 53)) srcport = s.getsockname()[1] # s.send("foo") # TODO: WHY DOES THIS NOT WORK? # Expect to see an UDP encapsulated packet. packets = self.ReadAllPacketsOn(netid) self.assertEquals(1, len(packets)) packet = packets[0] self.assertIsUdpEncapEsp(packet, out_spi, 1, 52) # Now test the receive path. Because we don't know how to decrypt packets, # we just play back the encrypted packet that kernel sent earlier. We swap # the addresses in the IP header to make the packet look like it's bound for # us, but we can't do that for the port numbers because the UDP header is # part of the integrity protected payload, which we can only replay as is. # So the source and destination ports are swapped and the packet appears to # be sent from srcport to port 53. Open another socket on that port, and # apply the inbound policy to it. twisted_socket = socket(AF_INET, SOCK_DGRAM, 0) net_test.SetSocketTimeout(twisted_socket, 100) twisted_socket.bind(("0.0.0.0", 53)) # TODO: why does this work even without the per-socket policy applied? The # received packet obviously matches an SA, but don't inbound packets need to # match a policy as well? info.dir = xfrm.XFRM_POLICY_IN xfrmid.spi = in_spi usertmpl.reqid = in_reqid data = info.Pack() + usertmpl.Pack() twisted_socket.setsockopt(IPPROTO_IP, xfrm.IP_XFRM_POLICY, data) # Save the payload of the packet so we can replay it back to ourselves. payload = str(packet.payload)[8:] spi_seq = struct.pack("!II", ntohl(in_spi), 1) payload = spi_seq + payload[len(spi_seq):] # Tamper with the packet and check that it's dropped and counted as invalid. sainfo = self.xfrm.FindSaInfo(in_spi) self.assertEquals(0, sainfo.stats.integrity_failed) broken = payload[:25] + chr( (ord(payload[25]) + 1) % 256) + payload[26:] incoming = (scapy.IP(src=remoteaddr, dst=myaddr) / scapy.UDP(sport=4500, dport=encap_port) / broken) self.ReceivePacketOn(netid, incoming) sainfo = self.xfrm.FindSaInfo(in_spi) self.assertEquals(1, sainfo.stats.integrity_failed) # Now play back the valid packet and check that we receive it. incoming = (scapy.IP(src=remoteaddr, dst=myaddr) / scapy.UDP(sport=4500, dport=encap_port) / payload) self.ReceivePacketOn(netid, incoming) data, src = twisted_socket.recvfrom(4096) self.assertEquals("foo", data) self.assertEquals((remoteaddr, srcport), src) # Check that unencrypted packets are not received. unencrypted = (scapy.IP(src=remoteaddr, dst=myaddr) / scapy.UDP(sport=srcport, dport=53) / "foo") self.assertRaisesErrno(EAGAIN, twisted_socket.recv, 4096)
def testProcNetRaw6(self): s = net_test.Socket(AF_INET6, SOCK_RAW, IPPROTO_RAW) s.bind(("::1", 0xace)) s.connect(("::1", 0xbeef)) self.CheckSockStatFile("raw6", "::1", 0xff, "::1", 0, 1)
def testProcNetUdp6(self): s = net_test.Socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP) s.bind(("::1", 0xace)) s.connect(("::1", 0xbeef)) self.CheckSockStatFile("udp6", "::1", 0xace, "::1", 0xbeef, 1)
def testProcNetIcmp(self): s = net_test.Socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP) s.bind(("127.0.0.1", 0xace)) s.connect(("127.0.0.1", 0xbeef)) self.CheckSockStatFile("icmp", "127.0.0.1", 0xace, "127.0.0.1", 0xbeef, 1)