1*2f2c4c7aSAndroid Build Coastguard Worker#!/usr/bin/python3 2*2f2c4c7aSAndroid Build Coastguard Worker# 3*2f2c4c7aSAndroid Build Coastguard Worker# Copyright 2017 The Android Open Source Project 4*2f2c4c7aSAndroid Build Coastguard Worker# 5*2f2c4c7aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 6*2f2c4c7aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 7*2f2c4c7aSAndroid Build Coastguard Worker# You may obtain a copy of the License at 8*2f2c4c7aSAndroid Build Coastguard Worker# 9*2f2c4c7aSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 10*2f2c4c7aSAndroid Build Coastguard Worker# 11*2f2c4c7aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 12*2f2c4c7aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 13*2f2c4c7aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*2f2c4c7aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 15*2f2c4c7aSAndroid Build Coastguard Worker# limitations under the License. 16*2f2c4c7aSAndroid Build Coastguard Worker 17*2f2c4c7aSAndroid Build Coastguard Worker# pylint: disable=g-bad-todo,g-bad-file-header,wildcard-import 18*2f2c4c7aSAndroid Build Coastguard Workerfrom errno import * # pylint: disable=wildcard-import 19*2f2c4c7aSAndroid Build Coastguard Workerfrom scapy import all as scapy 20*2f2c4c7aSAndroid Build Coastguard Workerfrom socket import * # pylint: disable=wildcard-import 21*2f2c4c7aSAndroid Build Coastguard Workerimport binascii 22*2f2c4c7aSAndroid Build Coastguard Workerimport struct 23*2f2c4c7aSAndroid Build Coastguard Workerimport subprocess 24*2f2c4c7aSAndroid Build Coastguard Workerimport threading 25*2f2c4c7aSAndroid Build Coastguard Workerimport unittest 26*2f2c4c7aSAndroid Build Coastguard Worker 27*2f2c4c7aSAndroid Build Coastguard Workerimport csocket 28*2f2c4c7aSAndroid Build Coastguard Workerimport cstruct 29*2f2c4c7aSAndroid Build Coastguard Workerimport multinetwork_base 30*2f2c4c7aSAndroid Build Coastguard Workerimport net_test 31*2f2c4c7aSAndroid Build Coastguard Workerimport packets 32*2f2c4c7aSAndroid Build Coastguard Workerimport xfrm 33*2f2c4c7aSAndroid Build Coastguard Workerimport xfrm_base 34*2f2c4c7aSAndroid Build Coastguard Worker 35*2f2c4c7aSAndroid Build Coastguard WorkerENCRYPTED_PAYLOAD = ("b1c74998efd6326faebe2061f00f2c750e90e76001664a80c287b150" 36*2f2c4c7aSAndroid Build Coastguard Worker "59e74bf949769cc6af71e51b539e7de3a2a14cb05a231b969e035174" 37*2f2c4c7aSAndroid Build Coastguard Worker "d98c5aa0cef1937db98889ec0d08fa408fecf616") 38*2f2c4c7aSAndroid Build Coastguard Worker 39*2f2c4c7aSAndroid Build Coastguard WorkerTEST_ADDR1 = "2001:4860:4860::8888" 40*2f2c4c7aSAndroid Build Coastguard WorkerTEST_ADDR2 = "2001:4860:4860::8844" 41*2f2c4c7aSAndroid Build Coastguard Worker 42*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_STATS_PROCFILE = "/proc/net/xfrm_stat" 43*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_STATS_OUT_NO_STATES = "XfrmOutNoStates" 44*2f2c4c7aSAndroid Build Coastguard Worker 45*2f2c4c7aSAndroid Build Coastguard Worker# IP addresses to use for tunnel endpoints. For generality, these should be 46*2f2c4c7aSAndroid Build Coastguard Worker# different from the addresses we send packets to. 47*2f2c4c7aSAndroid Build Coastguard WorkerTUNNEL_ENDPOINTS = {4: "8.8.4.4", 6: TEST_ADDR2} 48*2f2c4c7aSAndroid Build Coastguard Worker 49*2f2c4c7aSAndroid Build Coastguard WorkerTEST_SPI = 0x1234 50*2f2c4c7aSAndroid Build Coastguard WorkerTEST_SPI2 = 0x1235 51*2f2c4c7aSAndroid Build Coastguard Worker 52*2f2c4c7aSAndroid Build Coastguard Worker 53*2f2c4c7aSAndroid Build Coastguard Worker 54*2f2c4c7aSAndroid Build Coastguard Workerclass XfrmFunctionalTest(xfrm_base.XfrmLazyTest): 55*2f2c4c7aSAndroid Build Coastguard Worker 56*2f2c4c7aSAndroid Build Coastguard Worker def assertIsUdpEncapEsp(self, packet, spi, seq, length): 57*2f2c4c7aSAndroid Build Coastguard Worker protocol = packet.nh if packet.version == 6 else packet.proto 58*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(IPPROTO_UDP, protocol) 59*2f2c4c7aSAndroid Build Coastguard Worker udp_hdr = packet[scapy.UDP] 60*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(4500, udp_hdr.dport) 61*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(length, len(udp_hdr)) 62*2f2c4c7aSAndroid Build Coastguard Worker esp_hdr, _ = cstruct.Read(bytes(udp_hdr.payload), xfrm.EspHdr) 63*2f2c4c7aSAndroid Build Coastguard Worker # FIXME: this file currently swaps SPI byte order manually, so SPI needs to 64*2f2c4c7aSAndroid Build Coastguard Worker # be double-swapped here. 65*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(xfrm.EspHdr((spi, seq)), esp_hdr) 66*2f2c4c7aSAndroid Build Coastguard Worker 67*2f2c4c7aSAndroid Build Coastguard Worker def CreateNewSa(self, localAddr, remoteAddr, spi, reqId, encap_tmpl, 68*2f2c4c7aSAndroid Build Coastguard Worker null_auth=False): 69*2f2c4c7aSAndroid Build Coastguard Worker auth_algo = ( 70*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_AUTH_NULL if null_auth else xfrm_base._ALGO_HMAC_SHA1) 71*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddSaInfo(localAddr, remoteAddr, spi, xfrm.XFRM_MODE_TRANSPORT, 72*2f2c4c7aSAndroid Build Coastguard Worker reqId, xfrm_base._ALGO_CBC_AES_256, auth_algo, None, 73*2f2c4c7aSAndroid Build Coastguard Worker encap_tmpl, None, None) 74*2f2c4c7aSAndroid Build Coastguard Worker 75*2f2c4c7aSAndroid Build Coastguard Worker def testAddSa(self): 76*2f2c4c7aSAndroid Build Coastguard Worker self.CreateNewSa("::", TEST_ADDR1, TEST_SPI, 3320, None) 77*2f2c4c7aSAndroid Build Coastguard Worker expected = ( 78*2f2c4c7aSAndroid Build Coastguard Worker "src :: dst 2001:4860:4860::8888\n" 79*2f2c4c7aSAndroid Build Coastguard Worker "\tproto esp spi 0x00001234 reqid 3320 mode transport\n" 80*2f2c4c7aSAndroid Build Coastguard Worker "\treplay-window 32 \n" 81*2f2c4c7aSAndroid Build Coastguard Worker "\tauth-trunc hmac(sha1) 0x%s 96\n" 82*2f2c4c7aSAndroid Build Coastguard Worker "\tenc cbc(aes) 0x%s\n" 83*2f2c4c7aSAndroid Build Coastguard Worker "\tsel src ::/0 dst ::/0 \n" % ( 84*2f2c4c7aSAndroid Build Coastguard Worker binascii.hexlify(xfrm_base._AUTHENTICATION_KEY_128).decode("utf-8"), 85*2f2c4c7aSAndroid Build Coastguard Worker binascii.hexlify(xfrm_base._ENCRYPTION_KEY_256).decode("utf-8"))) 86*2f2c4c7aSAndroid Build Coastguard Worker 87*2f2c4c7aSAndroid Build Coastguard Worker actual = subprocess.check_output("ip xfrm state".split()).decode("utf-8") 88*2f2c4c7aSAndroid Build Coastguard Worker # Newer versions of IP also show anti-replay context. Don't choke if it's 89*2f2c4c7aSAndroid Build Coastguard Worker # missing. 90*2f2c4c7aSAndroid Build Coastguard Worker actual = actual.replace( 91*2f2c4c7aSAndroid Build Coastguard Worker "\tanti-replay context: seq 0x0, oseq 0x0, bitmap 0x00000000\n", "") 92*2f2c4c7aSAndroid Build Coastguard Worker try: 93*2f2c4c7aSAndroid Build Coastguard Worker self.assertMultiLineEqual(expected, actual) 94*2f2c4c7aSAndroid Build Coastguard Worker finally: 95*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.DeleteSaInfo(TEST_ADDR1, TEST_SPI, IPPROTO_ESP) 96*2f2c4c7aSAndroid Build Coastguard Worker 97*2f2c4c7aSAndroid Build Coastguard Worker def testFlush(self): 98*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(0, len(self.xfrm.DumpSaInfo())) 99*2f2c4c7aSAndroid Build Coastguard Worker self.CreateNewSa("::", "2000::", TEST_SPI, 1234, None) 100*2f2c4c7aSAndroid Build Coastguard Worker self.CreateNewSa("0.0.0.0", "192.0.2.1", TEST_SPI, 4321, None) 101*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(2, len(self.xfrm.DumpSaInfo())) 102*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.FlushSaInfo() 103*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(0, len(self.xfrm.DumpSaInfo())) 104*2f2c4c7aSAndroid Build Coastguard Worker 105*2f2c4c7aSAndroid Build Coastguard Worker def _TestSocketPolicy(self, version): 106*2f2c4c7aSAndroid Build Coastguard Worker # Open a UDP socket and connect it. 107*2f2c4c7aSAndroid Build Coastguard Worker family = net_test.GetAddressFamily(version) 108*2f2c4c7aSAndroid Build Coastguard Worker s = socket(family, SOCK_DGRAM, 0) 109*2f2c4c7aSAndroid Build Coastguard Worker netid = self.RandomNetid() 110*2f2c4c7aSAndroid Build Coastguard Worker self.SelectInterface(s, netid, "mark") 111*2f2c4c7aSAndroid Build Coastguard Worker 112*2f2c4c7aSAndroid Build Coastguard Worker remotesockaddr = self.GetRemoteSocketAddress(version) 113*2f2c4c7aSAndroid Build Coastguard Worker s.connect((remotesockaddr, 53)) 114*2f2c4c7aSAndroid Build Coastguard Worker saddr, sport = s.getsockname()[:2] 115*2f2c4c7aSAndroid Build Coastguard Worker daddr, dport = s.getpeername()[:2] 116*2f2c4c7aSAndroid Build Coastguard Worker if version == 5: 117*2f2c4c7aSAndroid Build Coastguard Worker saddr = saddr.replace("::ffff:", "") 118*2f2c4c7aSAndroid Build Coastguard Worker daddr = daddr.replace("::ffff:", "") 119*2f2c4c7aSAndroid Build Coastguard Worker 120*2f2c4c7aSAndroid Build Coastguard Worker reqid = 0 121*2f2c4c7aSAndroid Build Coastguard Worker 122*2f2c4c7aSAndroid Build Coastguard Worker desc, pkt = packets.UDP(version, saddr, daddr, sport=sport) 123*2f2c4c7aSAndroid Build Coastguard Worker s.sendto(net_test.UDP_PAYLOAD, (remotesockaddr, 53)) 124*2f2c4c7aSAndroid Build Coastguard Worker self.ExpectPacketOn(netid, "Send after socket, expected %s" % desc, pkt) 125*2f2c4c7aSAndroid Build Coastguard Worker 126*2f2c4c7aSAndroid Build Coastguard Worker # Using IPv4 XFRM on a dual-stack socket requires setting an AF_INET policy 127*2f2c4c7aSAndroid Build Coastguard Worker # that's written in terms of IPv4 addresses. 128*2f2c4c7aSAndroid Build Coastguard Worker xfrm_version = 4 if version == 5 else version 129*2f2c4c7aSAndroid Build Coastguard Worker xfrm_family = net_test.GetAddressFamily(xfrm_version) 130*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base.ApplySocketPolicy(s, xfrm_family, xfrm.XFRM_POLICY_OUT, 131*2f2c4c7aSAndroid Build Coastguard Worker TEST_SPI, reqid, None) 132*2f2c4c7aSAndroid Build Coastguard Worker 133*2f2c4c7aSAndroid Build Coastguard Worker # Because the policy has level set to "require" (the default), attempting 134*2f2c4c7aSAndroid Build Coastguard Worker # to send a packet results in an error, because there is no SA that 135*2f2c4c7aSAndroid Build Coastguard Worker # matches the socket policy we set. 136*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno( 137*2f2c4c7aSAndroid Build Coastguard Worker EAGAIN, 138*2f2c4c7aSAndroid Build Coastguard Worker s.sendto, net_test.UDP_PAYLOAD, (remotesockaddr, 53)) 139*2f2c4c7aSAndroid Build Coastguard Worker 140*2f2c4c7aSAndroid Build Coastguard Worker # If there is a user space key manager, calling sendto() after applying the socket policy 141*2f2c4c7aSAndroid Build Coastguard Worker # creates an SA whose state is XFRM_STATE_ACQ. So this just deletes it. 142*2f2c4c7aSAndroid Build Coastguard Worker # If there is no user space key manager, deleting SA returns ESRCH as the error code. 143*2f2c4c7aSAndroid Build Coastguard Worker try: 144*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.DeleteSaInfo(self.GetRemoteAddress(xfrm_version), TEST_SPI, IPPROTO_ESP) 145*2f2c4c7aSAndroid Build Coastguard Worker except IOError as e: 146*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(ESRCH, e.errno, "Unexpected error when deleting ACQ SA") 147*2f2c4c7aSAndroid Build Coastguard Worker 148*2f2c4c7aSAndroid Build Coastguard Worker # Adding a matching SA causes the packet to go out encrypted. The SA's 149*2f2c4c7aSAndroid Build Coastguard Worker # SPI must match the one in our template, and the destination address must 150*2f2c4c7aSAndroid Build Coastguard Worker # match the packet's destination address (in tunnel mode, it has to match 151*2f2c4c7aSAndroid Build Coastguard Worker # the tunnel destination). 152*2f2c4c7aSAndroid Build Coastguard Worker self.CreateNewSa( 153*2f2c4c7aSAndroid Build Coastguard Worker net_test.GetWildcardAddress(xfrm_version), 154*2f2c4c7aSAndroid Build Coastguard Worker self.GetRemoteAddress(xfrm_version), TEST_SPI, reqid, None) 155*2f2c4c7aSAndroid Build Coastguard Worker 156*2f2c4c7aSAndroid Build Coastguard Worker s.sendto(net_test.UDP_PAYLOAD, (remotesockaddr, 53)) 157*2f2c4c7aSAndroid Build Coastguard Worker expected_length = xfrm_base.GetEspPacketLength(xfrm.XFRM_MODE_TRANSPORT, 158*2f2c4c7aSAndroid Build Coastguard Worker version, False, 159*2f2c4c7aSAndroid Build Coastguard Worker net_test.UDP_PAYLOAD, 160*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_HMAC_SHA1, 161*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_CBC_AES_256) 162*2f2c4c7aSAndroid Build Coastguard Worker self._ExpectEspPacketOn(netid, TEST_SPI, 1, expected_length, None, None) 163*2f2c4c7aSAndroid Build Coastguard Worker 164*2f2c4c7aSAndroid Build Coastguard Worker # Sending to another destination doesn't work: again, no matching SA. 165*2f2c4c7aSAndroid Build Coastguard Worker remoteaddr2 = self.GetOtherRemoteSocketAddress(version) 166*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno( 167*2f2c4c7aSAndroid Build Coastguard Worker EAGAIN, 168*2f2c4c7aSAndroid Build Coastguard Worker s.sendto, net_test.UDP_PAYLOAD, (remoteaddr2, 53)) 169*2f2c4c7aSAndroid Build Coastguard Worker 170*2f2c4c7aSAndroid Build Coastguard Worker # Sending on another socket without the policy applied results in an 171*2f2c4c7aSAndroid Build Coastguard Worker # unencrypted packet going out. 172*2f2c4c7aSAndroid Build Coastguard Worker s2 = socket(family, SOCK_DGRAM, 0) 173*2f2c4c7aSAndroid Build Coastguard Worker self.SelectInterface(s2, netid, "mark") 174*2f2c4c7aSAndroid Build Coastguard Worker s2.sendto(net_test.UDP_PAYLOAD, (remotesockaddr, 53)) 175*2f2c4c7aSAndroid Build Coastguard Worker pkts = self.ReadAllPacketsOn(netid) 176*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(1, len(pkts)) 177*2f2c4c7aSAndroid Build Coastguard Worker packet = pkts[0] 178*2f2c4c7aSAndroid Build Coastguard Worker 179*2f2c4c7aSAndroid Build Coastguard Worker protocol = packet.nh if version == 6 else packet.proto 180*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(IPPROTO_UDP, protocol) 181*2f2c4c7aSAndroid Build Coastguard Worker 182*2f2c4c7aSAndroid Build Coastguard Worker # Deleting the SA causes the first socket to return errors again. 183*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.DeleteSaInfo(self.GetRemoteAddress(xfrm_version), TEST_SPI, 184*2f2c4c7aSAndroid Build Coastguard Worker IPPROTO_ESP) 185*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno( 186*2f2c4c7aSAndroid Build Coastguard Worker EAGAIN, 187*2f2c4c7aSAndroid Build Coastguard Worker s.sendto, net_test.UDP_PAYLOAD, (remotesockaddr, 53)) 188*2f2c4c7aSAndroid Build Coastguard Worker 189*2f2c4c7aSAndroid Build Coastguard Worker # Clear the socket policy and expect a cleartext packet. 190*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base.SetPolicySockopt(s, family, None) 191*2f2c4c7aSAndroid Build Coastguard Worker s.sendto(net_test.UDP_PAYLOAD, (remotesockaddr, 53)) 192*2f2c4c7aSAndroid Build Coastguard Worker self.ExpectPacketOn(netid, "Send after clear, expected %s" % desc, pkt) 193*2f2c4c7aSAndroid Build Coastguard Worker 194*2f2c4c7aSAndroid Build Coastguard Worker # Clearing the policy twice is safe. 195*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base.SetPolicySockopt(s, family, None) 196*2f2c4c7aSAndroid Build Coastguard Worker s.sendto(net_test.UDP_PAYLOAD, (remotesockaddr, 53)) 197*2f2c4c7aSAndroid Build Coastguard Worker self.ExpectPacketOn(netid, "Send after clear 2, expected %s" % desc, pkt) 198*2f2c4c7aSAndroid Build Coastguard Worker s.close() 199*2f2c4c7aSAndroid Build Coastguard Worker 200*2f2c4c7aSAndroid Build Coastguard Worker # Clearing if a policy was never set is safe. 201*2f2c4c7aSAndroid Build Coastguard Worker s = socket(AF_INET6, SOCK_DGRAM, 0) 202*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base.SetPolicySockopt(s, family, None) 203*2f2c4c7aSAndroid Build Coastguard Worker 204*2f2c4c7aSAndroid Build Coastguard Worker s.close() 205*2f2c4c7aSAndroid Build Coastguard Worker s2.close() 206*2f2c4c7aSAndroid Build Coastguard Worker 207*2f2c4c7aSAndroid Build Coastguard Worker def testSocketPolicyIPv4(self): 208*2f2c4c7aSAndroid Build Coastguard Worker self._TestSocketPolicy(4) 209*2f2c4c7aSAndroid Build Coastguard Worker 210*2f2c4c7aSAndroid Build Coastguard Worker def testSocketPolicyIPv6(self): 211*2f2c4c7aSAndroid Build Coastguard Worker self._TestSocketPolicy(6) 212*2f2c4c7aSAndroid Build Coastguard Worker 213*2f2c4c7aSAndroid Build Coastguard Worker def testSocketPolicyMapped(self): 214*2f2c4c7aSAndroid Build Coastguard Worker self._TestSocketPolicy(5) 215*2f2c4c7aSAndroid Build Coastguard Worker 216*2f2c4c7aSAndroid Build Coastguard Worker # Sets up sockets and marks to correct netid 217*2f2c4c7aSAndroid Build Coastguard Worker def _SetupUdpEncapSockets(self, version): 218*2f2c4c7aSAndroid Build Coastguard Worker netid = self.RandomNetid() 219*2f2c4c7aSAndroid Build Coastguard Worker myaddr = self.MyAddress(version, netid) 220*2f2c4c7aSAndroid Build Coastguard Worker remoteaddr = self.GetRemoteAddress(version) 221*2f2c4c7aSAndroid Build Coastguard Worker family = net_test.GetAddressFamily(version) 222*2f2c4c7aSAndroid Build Coastguard Worker 223*2f2c4c7aSAndroid Build Coastguard Worker # Reserve a port on which to receive UDP encapsulated packets. Sending 224*2f2c4c7aSAndroid Build Coastguard Worker # packets works without this (and potentially can send packets with a source 225*2f2c4c7aSAndroid Build Coastguard Worker # port belonging to another application), but receiving requires the port to 226*2f2c4c7aSAndroid Build Coastguard Worker # be bound and the encapsulation socket option enabled. 227*2f2c4c7aSAndroid Build Coastguard Worker encap_sock = net_test.Socket(family, SOCK_DGRAM, 0) 228*2f2c4c7aSAndroid Build Coastguard Worker encap_sock.bind((myaddr, 0)) 229*2f2c4c7aSAndroid Build Coastguard Worker encap_port = encap_sock.getsockname()[1] 230*2f2c4c7aSAndroid Build Coastguard Worker encap_sock.setsockopt(IPPROTO_UDP, xfrm.UDP_ENCAP, xfrm.UDP_ENCAP_ESPINUDP) 231*2f2c4c7aSAndroid Build Coastguard Worker 232*2f2c4c7aSAndroid Build Coastguard Worker # Open a socket to send traffic. 233*2f2c4c7aSAndroid Build Coastguard Worker # TODO: test with a different family than the encap socket. 234*2f2c4c7aSAndroid Build Coastguard Worker s = socket(family, SOCK_DGRAM, 0) 235*2f2c4c7aSAndroid Build Coastguard Worker self.SelectInterface(s, netid, "mark") 236*2f2c4c7aSAndroid Build Coastguard Worker s.connect((remoteaddr, 53)) 237*2f2c4c7aSAndroid Build Coastguard Worker 238*2f2c4c7aSAndroid Build Coastguard Worker return netid, myaddr, remoteaddr, encap_sock, encap_port, s 239*2f2c4c7aSAndroid Build Coastguard Worker 240*2f2c4c7aSAndroid Build Coastguard Worker # Sets up SAs and applies socket policy to given socket 241*2f2c4c7aSAndroid Build Coastguard Worker def _SetupUdpEncapSaPair(self, version, myaddr, remoteaddr, in_spi, out_spi, 242*2f2c4c7aSAndroid Build Coastguard Worker encap_port, s, use_null_auth): 243*2f2c4c7aSAndroid Build Coastguard Worker in_reqid = 123 244*2f2c4c7aSAndroid Build Coastguard Worker out_reqid = 456 245*2f2c4c7aSAndroid Build Coastguard Worker 246*2f2c4c7aSAndroid Build Coastguard Worker # Create inbound and outbound SAs that specify UDP encapsulation. 247*2f2c4c7aSAndroid Build Coastguard Worker encaptmpl = xfrm.XfrmEncapTmpl((xfrm.UDP_ENCAP_ESPINUDP, htons(encap_port), 248*2f2c4c7aSAndroid Build Coastguard Worker htons(4500), 16 * b"\x00")) 249*2f2c4c7aSAndroid Build Coastguard Worker self.CreateNewSa(myaddr, remoteaddr, out_spi, out_reqid, encaptmpl, 250*2f2c4c7aSAndroid Build Coastguard Worker use_null_auth) 251*2f2c4c7aSAndroid Build Coastguard Worker 252*2f2c4c7aSAndroid Build Coastguard Worker # Add an encap template that's the mirror of the outbound one. 253*2f2c4c7aSAndroid Build Coastguard Worker encaptmpl.sport, encaptmpl.dport = encaptmpl.dport, encaptmpl.sport 254*2f2c4c7aSAndroid Build Coastguard Worker self.CreateNewSa(remoteaddr, myaddr, in_spi, in_reqid, encaptmpl, 255*2f2c4c7aSAndroid Build Coastguard Worker use_null_auth) 256*2f2c4c7aSAndroid Build Coastguard Worker 257*2f2c4c7aSAndroid Build Coastguard Worker # Apply socket policies to s. 258*2f2c4c7aSAndroid Build Coastguard Worker family = net_test.GetAddressFamily(version) 259*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base.ApplySocketPolicy(s, family, xfrm.XFRM_POLICY_OUT, out_spi, 260*2f2c4c7aSAndroid Build Coastguard Worker out_reqid, None) 261*2f2c4c7aSAndroid Build Coastguard Worker 262*2f2c4c7aSAndroid Build Coastguard Worker # TODO: why does this work without a per-socket policy applied? 263*2f2c4c7aSAndroid Build Coastguard Worker # The received packet obviously matches an SA, but don't inbound packets 264*2f2c4c7aSAndroid Build Coastguard Worker # need to match a policy as well? (b/71541609) 265*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base.ApplySocketPolicy(s, family, xfrm.XFRM_POLICY_IN, in_spi, 266*2f2c4c7aSAndroid Build Coastguard Worker in_reqid, None) 267*2f2c4c7aSAndroid Build Coastguard Worker 268*2f2c4c7aSAndroid Build Coastguard Worker # Uncomment for debugging. 269*2f2c4c7aSAndroid Build Coastguard Worker # subprocess.call("ip xfrm state".split()) 270*2f2c4c7aSAndroid Build Coastguard Worker 271*2f2c4c7aSAndroid Build Coastguard Worker # Check that packets can be sent and received. 272*2f2c4c7aSAndroid Build Coastguard Worker def _VerifyUdpEncapSocket(self, version, netid, remoteaddr, myaddr, encap_port, 273*2f2c4c7aSAndroid Build Coastguard Worker sock, in_spi, out_spi, null_auth, seq_num): 274*2f2c4c7aSAndroid Build Coastguard Worker # Now send a packet. 275*2f2c4c7aSAndroid Build Coastguard Worker sock.sendto(net_test.UDP_PAYLOAD, (remoteaddr, 53)) 276*2f2c4c7aSAndroid Build Coastguard Worker srcport = sock.getsockname()[1] 277*2f2c4c7aSAndroid Build Coastguard Worker 278*2f2c4c7aSAndroid Build Coastguard Worker # Expect to see an UDP encapsulated packet. 279*2f2c4c7aSAndroid Build Coastguard Worker pkts = self.ReadAllPacketsOn(netid) 280*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(1, len(pkts)) 281*2f2c4c7aSAndroid Build Coastguard Worker packet = pkts[0] 282*2f2c4c7aSAndroid Build Coastguard Worker 283*2f2c4c7aSAndroid Build Coastguard Worker auth_algo = ( 284*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_AUTH_NULL if null_auth else xfrm_base._ALGO_HMAC_SHA1) 285*2f2c4c7aSAndroid Build Coastguard Worker expected_len = xfrm_base.GetEspPacketLength( 286*2f2c4c7aSAndroid Build Coastguard Worker xfrm.XFRM_MODE_TRANSPORT, version, True, net_test.UDP_PAYLOAD, 287*2f2c4c7aSAndroid Build Coastguard Worker auth_algo, xfrm_base._ALGO_CBC_AES_256) 288*2f2c4c7aSAndroid Build Coastguard Worker self.assertIsUdpEncapEsp(packet, out_spi, seq_num, expected_len) 289*2f2c4c7aSAndroid Build Coastguard Worker 290*2f2c4c7aSAndroid Build Coastguard Worker # Now test the receive path. Because we don't know how to decrypt packets, 291*2f2c4c7aSAndroid Build Coastguard Worker # we just play back the encrypted packet that kernel sent earlier. We swap 292*2f2c4c7aSAndroid Build Coastguard Worker # the addresses in the IP header to make the packet look like it's bound for 293*2f2c4c7aSAndroid Build Coastguard Worker # us, but we can't do that for the port numbers because the UDP header is 294*2f2c4c7aSAndroid Build Coastguard Worker # part of the integrity protected payload, which we can only replay as is. 295*2f2c4c7aSAndroid Build Coastguard Worker # So the source and destination ports are swapped and the packet appears to 296*2f2c4c7aSAndroid Build Coastguard Worker # be sent from srcport to port 53. Open another socket on that port, and 297*2f2c4c7aSAndroid Build Coastguard Worker # apply the inbound policy to it. 298*2f2c4c7aSAndroid Build Coastguard Worker family = net_test.GetAddressFamily(version) 299*2f2c4c7aSAndroid Build Coastguard Worker twisted_socket = socket(family, SOCK_DGRAM, 0) 300*2f2c4c7aSAndroid Build Coastguard Worker csocket.SetSocketTimeout(twisted_socket, 100) 301*2f2c4c7aSAndroid Build Coastguard Worker twisted_socket.bind((net_test.GetWildcardAddress(version), 53)) 302*2f2c4c7aSAndroid Build Coastguard Worker 303*2f2c4c7aSAndroid Build Coastguard Worker # Save the payload of the packet so we can replay it back to ourselves, and 304*2f2c4c7aSAndroid Build Coastguard Worker # replace the SPI with our inbound SPI. 305*2f2c4c7aSAndroid Build Coastguard Worker payload = bytes(packet.payload)[8:] 306*2f2c4c7aSAndroid Build Coastguard Worker spi_seq = xfrm.EspHdr((in_spi, seq_num)).Pack() 307*2f2c4c7aSAndroid Build Coastguard Worker payload = spi_seq + payload[len(spi_seq):] 308*2f2c4c7aSAndroid Build Coastguard Worker 309*2f2c4c7aSAndroid Build Coastguard Worker sainfo = self.xfrm.FindSaInfo(in_spi) 310*2f2c4c7aSAndroid Build Coastguard Worker start_integrity_failures = sainfo.stats.integrity_failed 311*2f2c4c7aSAndroid Build Coastguard Worker 312*2f2c4c7aSAndroid Build Coastguard Worker # Now play back the valid packet and check that we receive it. 313*2f2c4c7aSAndroid Build Coastguard Worker ip = {4: scapy.IP, 6: scapy.IPv6}[version] 314*2f2c4c7aSAndroid Build Coastguard Worker incoming = (ip(src=remoteaddr, dst=myaddr) / 315*2f2c4c7aSAndroid Build Coastguard Worker scapy.UDP(sport=4500, dport=encap_port) / payload) 316*2f2c4c7aSAndroid Build Coastguard Worker incoming = ip(bytes(incoming)) 317*2f2c4c7aSAndroid Build Coastguard Worker self.ReceivePacketOn(netid, incoming) 318*2f2c4c7aSAndroid Build Coastguard Worker 319*2f2c4c7aSAndroid Build Coastguard Worker sainfo = self.xfrm.FindSaInfo(in_spi) 320*2f2c4c7aSAndroid Build Coastguard Worker 321*2f2c4c7aSAndroid Build Coastguard Worker # TODO: break this out into a separate test 322*2f2c4c7aSAndroid Build Coastguard Worker # If our SPIs are different, and we aren't using null authentication, 323*2f2c4c7aSAndroid Build Coastguard Worker # we expect the packet to be dropped. We also expect that the integrity 324*2f2c4c7aSAndroid Build Coastguard Worker # failure counter to increase, as SPIs are part of the authenticated or 325*2f2c4c7aSAndroid Build Coastguard Worker # integrity-verified portion of the packet. 326*2f2c4c7aSAndroid Build Coastguard Worker if not null_auth and in_spi != out_spi: 327*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno(EAGAIN, twisted_socket.recv, 4096) 328*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(start_integrity_failures + 1, 329*2f2c4c7aSAndroid Build Coastguard Worker sainfo.stats.integrity_failed) 330*2f2c4c7aSAndroid Build Coastguard Worker else: 331*2f2c4c7aSAndroid Build Coastguard Worker data, src = twisted_socket.recvfrom(4096) 332*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(net_test.UDP_PAYLOAD, data) 333*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual((remoteaddr, srcport), src[:2]) 334*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(start_integrity_failures, sainfo.stats.integrity_failed) 335*2f2c4c7aSAndroid Build Coastguard Worker 336*2f2c4c7aSAndroid Build Coastguard Worker # Check that unencrypted packets on twisted_socket are not received. 337*2f2c4c7aSAndroid Build Coastguard Worker unencrypted = ( 338*2f2c4c7aSAndroid Build Coastguard Worker ip(src=remoteaddr, dst=myaddr) / scapy.UDP( 339*2f2c4c7aSAndroid Build Coastguard Worker sport=srcport, dport=53) / net_test.UDP_PAYLOAD) 340*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno(EAGAIN, twisted_socket.recv, 4096) 341*2f2c4c7aSAndroid Build Coastguard Worker 342*2f2c4c7aSAndroid Build Coastguard Worker twisted_socket.close() 343*2f2c4c7aSAndroid Build Coastguard Worker 344*2f2c4c7aSAndroid Build Coastguard Worker def _RunEncapSocketPolicyTest(self, version, in_spi, out_spi, use_null_auth): 345*2f2c4c7aSAndroid Build Coastguard Worker netid, myaddr, remoteaddr, encap_sock, encap_port, s = \ 346*2f2c4c7aSAndroid Build Coastguard Worker self._SetupUdpEncapSockets(version) 347*2f2c4c7aSAndroid Build Coastguard Worker 348*2f2c4c7aSAndroid Build Coastguard Worker self._SetupUdpEncapSaPair(version, myaddr, remoteaddr, in_spi, out_spi, 349*2f2c4c7aSAndroid Build Coastguard Worker encap_port, s, use_null_auth) 350*2f2c4c7aSAndroid Build Coastguard Worker 351*2f2c4c7aSAndroid Build Coastguard Worker # Check that UDP encap sockets work with socket policy and given SAs 352*2f2c4c7aSAndroid Build Coastguard Worker self._VerifyUdpEncapSocket(version, netid, remoteaddr, myaddr, encap_port, 353*2f2c4c7aSAndroid Build Coastguard Worker s, in_spi, out_spi, use_null_auth, 1) 354*2f2c4c7aSAndroid Build Coastguard Worker encap_sock.close() 355*2f2c4c7aSAndroid Build Coastguard Worker s.close() 356*2f2c4c7aSAndroid Build Coastguard Worker 357*2f2c4c7aSAndroid Build Coastguard Worker # TODO: Add tests for ESP (non-encap) sockets. 358*2f2c4c7aSAndroid Build Coastguard Worker def testUdpEncapSameSpisNullAuth(self): 359*2f2c4c7aSAndroid Build Coastguard Worker # Use the same SPI both inbound and outbound because this lets us receive 360*2f2c4c7aSAndroid Build Coastguard Worker # encrypted packets by simply replaying the packets the kernel sends 361*2f2c4c7aSAndroid Build Coastguard Worker # without having to disable authentication 362*2f2c4c7aSAndroid Build Coastguard Worker self._RunEncapSocketPolicyTest(4, TEST_SPI, TEST_SPI, True) 363*2f2c4c7aSAndroid Build Coastguard Worker 364*2f2c4c7aSAndroid Build Coastguard Worker def testUdpEncapSameSpis(self): 365*2f2c4c7aSAndroid Build Coastguard Worker self._RunEncapSocketPolicyTest(4, TEST_SPI, TEST_SPI, False) 366*2f2c4c7aSAndroid Build Coastguard Worker 367*2f2c4c7aSAndroid Build Coastguard Worker def testUdpEncapDifferentSpisNullAuth(self): 368*2f2c4c7aSAndroid Build Coastguard Worker self._RunEncapSocketPolicyTest(4, TEST_SPI, TEST_SPI2, True) 369*2f2c4c7aSAndroid Build Coastguard Worker 370*2f2c4c7aSAndroid Build Coastguard Worker def testUdpEncapDifferentSpis(self): 371*2f2c4c7aSAndroid Build Coastguard Worker self._RunEncapSocketPolicyTest(4, TEST_SPI, TEST_SPI2, False) 372*2f2c4c7aSAndroid Build Coastguard Worker 373*2f2c4c7aSAndroid Build Coastguard Worker def testUdpEncapRekey(self): 374*2f2c4c7aSAndroid Build Coastguard Worker # Select the two SPIs that will be used 375*2f2c4c7aSAndroid Build Coastguard Worker start_spi = TEST_SPI 376*2f2c4c7aSAndroid Build Coastguard Worker rekey_spi = TEST_SPI2 377*2f2c4c7aSAndroid Build Coastguard Worker 378*2f2c4c7aSAndroid Build Coastguard Worker # Setup sockets 379*2f2c4c7aSAndroid Build Coastguard Worker netid, myaddr, remoteaddr, encap_sock, encap_port, s = \ 380*2f2c4c7aSAndroid Build Coastguard Worker self._SetupUdpEncapSockets(4) 381*2f2c4c7aSAndroid Build Coastguard Worker 382*2f2c4c7aSAndroid Build Coastguard Worker # The SAs must use null authentication, since we change SPIs on the fly 383*2f2c4c7aSAndroid Build Coastguard Worker # Without null authentication, this would result in an ESP authentication 384*2f2c4c7aSAndroid Build Coastguard Worker # error since the SPI is part of the authenticated section. The packet 385*2f2c4c7aSAndroid Build Coastguard Worker # would then be dropped 386*2f2c4c7aSAndroid Build Coastguard Worker self._SetupUdpEncapSaPair(4, myaddr, remoteaddr, start_spi, start_spi, 387*2f2c4c7aSAndroid Build Coastguard Worker encap_port, s, True) 388*2f2c4c7aSAndroid Build Coastguard Worker 389*2f2c4c7aSAndroid Build Coastguard Worker # Check that UDP encap sockets work with socket policy and given SAs 390*2f2c4c7aSAndroid Build Coastguard Worker self._VerifyUdpEncapSocket(4, netid, remoteaddr, myaddr, encap_port, s, 391*2f2c4c7aSAndroid Build Coastguard Worker start_spi, start_spi, True, 1) 392*2f2c4c7aSAndroid Build Coastguard Worker 393*2f2c4c7aSAndroid Build Coastguard Worker # Rekey this socket using the make-before-break paradigm. First we create 394*2f2c4c7aSAndroid Build Coastguard Worker # new SAs, update the per-socket policies, and only then remove the old SAs 395*2f2c4c7aSAndroid Build Coastguard Worker # 396*2f2c4c7aSAndroid Build Coastguard Worker # This allows us to switch to the new SA without breaking the outbound path. 397*2f2c4c7aSAndroid Build Coastguard Worker self._SetupUdpEncapSaPair(4, myaddr, remoteaddr, rekey_spi, rekey_spi, 398*2f2c4c7aSAndroid Build Coastguard Worker encap_port, s, True) 399*2f2c4c7aSAndroid Build Coastguard Worker 400*2f2c4c7aSAndroid Build Coastguard Worker # Check that UDP encap socket works with updated socket policy, sending 401*2f2c4c7aSAndroid Build Coastguard Worker # using new SA, but receiving on both old and new SAs 402*2f2c4c7aSAndroid Build Coastguard Worker self._VerifyUdpEncapSocket(4, netid, remoteaddr, myaddr, encap_port, s, 403*2f2c4c7aSAndroid Build Coastguard Worker rekey_spi, rekey_spi, True, 1) 404*2f2c4c7aSAndroid Build Coastguard Worker self._VerifyUdpEncapSocket(4, netid, remoteaddr, myaddr, encap_port, s, 405*2f2c4c7aSAndroid Build Coastguard Worker start_spi, rekey_spi, True, 2) 406*2f2c4c7aSAndroid Build Coastguard Worker 407*2f2c4c7aSAndroid Build Coastguard Worker # Delete old SAs 408*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.DeleteSaInfo(remoteaddr, start_spi, IPPROTO_ESP) 409*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.DeleteSaInfo(myaddr, start_spi, IPPROTO_ESP) 410*2f2c4c7aSAndroid Build Coastguard Worker 411*2f2c4c7aSAndroid Build Coastguard Worker # Check that UDP encap socket works with updated socket policy and new SAs 412*2f2c4c7aSAndroid Build Coastguard Worker self._VerifyUdpEncapSocket(4, netid, remoteaddr, myaddr, encap_port, s, 413*2f2c4c7aSAndroid Build Coastguard Worker rekey_spi, rekey_spi, True, 3) 414*2f2c4c7aSAndroid Build Coastguard Worker encap_sock.close() 415*2f2c4c7aSAndroid Build Coastguard Worker s.close() 416*2f2c4c7aSAndroid Build Coastguard Worker 417*2f2c4c7aSAndroid Build Coastguard Worker def _CheckUDPEncapRecv(self, version, mode): 418*2f2c4c7aSAndroid Build Coastguard Worker netid, myaddr, remoteaddr, encap_sock, encap_port, s = \ 419*2f2c4c7aSAndroid Build Coastguard Worker self._SetupUdpEncapSockets(version) 420*2f2c4c7aSAndroid Build Coastguard Worker 421*2f2c4c7aSAndroid Build Coastguard Worker # Create inbound and outbound SAs that specify UDP encapsulation. 422*2f2c4c7aSAndroid Build Coastguard Worker reqid = 123 423*2f2c4c7aSAndroid Build Coastguard Worker encaptmpl = xfrm.XfrmEncapTmpl((xfrm.UDP_ENCAP_ESPINUDP, htons(encap_port), 424*2f2c4c7aSAndroid Build Coastguard Worker htons(4500), 16 * b"\x00")) 425*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddSaInfo(remoteaddr, myaddr, TEST_SPI, mode, reqid, 426*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_CRYPT_NULL, xfrm_base._ALGO_AUTH_NULL, None, 427*2f2c4c7aSAndroid Build Coastguard Worker encaptmpl, None, None) 428*2f2c4c7aSAndroid Build Coastguard Worker 429*2f2c4c7aSAndroid Build Coastguard Worker sainfo = self.xfrm.FindSaInfo(TEST_SPI) 430*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(0, sainfo.curlft.packets) 431*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(0, sainfo.curlft.bytes) 432*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(0, sainfo.stats.integrity_failed) 433*2f2c4c7aSAndroid Build Coastguard Worker 434*2f2c4c7aSAndroid Build Coastguard Worker IpType = {4: scapy.IP, 6: scapy.IPv6}[version] 435*2f2c4c7aSAndroid Build Coastguard Worker if mode == xfrm.XFRM_MODE_TRANSPORT: 436*2f2c4c7aSAndroid Build Coastguard Worker # Due to a bug in the IPv6 UDP encap code, there must be at least 32 437*2f2c4c7aSAndroid Build Coastguard Worker # bytes after the ESP header or the packet will be dropped. 438*2f2c4c7aSAndroid Build Coastguard Worker # 8 (UDP header) + 18 (payload) + 2 (ESP trailer) = 28, dropped 439*2f2c4c7aSAndroid Build Coastguard Worker # 8 (UDP header) + 19 (payload) + 4 (ESP trailer) = 32, received 440*2f2c4c7aSAndroid Build Coastguard Worker # There is a similar bug in IPv4 encap, but the minimum is only 12 bytes, 441*2f2c4c7aSAndroid Build Coastguard Worker # which is much less likely to occur. This doesn't affect tunnel mode 442*2f2c4c7aSAndroid Build Coastguard Worker # because IP headers are always at least 20 bytes long. 443*2f2c4c7aSAndroid Build Coastguard Worker data = 19 * b"a" 444*2f2c4c7aSAndroid Build Coastguard Worker datalen = len(data) 445*2f2c4c7aSAndroid Build Coastguard Worker # TODO: update scapy and use scapy.ESP instead of manually generating ESP header. 446*2f2c4c7aSAndroid Build Coastguard Worker inner_pkt = xfrm.EspHdr(spi=TEST_SPI, seqnum=1).Pack() + bytes( 447*2f2c4c7aSAndroid Build Coastguard Worker scapy.UDP(sport=443, dport=32123) / data) + bytes( 448*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base.GetEspTrailer(len(data), IPPROTO_UDP)) 449*2f2c4c7aSAndroid Build Coastguard Worker input_pkt = (IpType(src=remoteaddr, dst=myaddr) / 450*2f2c4c7aSAndroid Build Coastguard Worker scapy.UDP(sport=4500, dport=encap_port) / 451*2f2c4c7aSAndroid Build Coastguard Worker inner_pkt) 452*2f2c4c7aSAndroid Build Coastguard Worker else: 453*2f2c4c7aSAndroid Build Coastguard Worker # TODO: test IPv4 in IPv6 encap and vice versa. 454*2f2c4c7aSAndroid Build Coastguard Worker data = b"" # Empty UDP payload 455*2f2c4c7aSAndroid Build Coastguard Worker datalen = {4: 20, 6: 40}[version] + len(data) 456*2f2c4c7aSAndroid Build Coastguard Worker # TODO: update scapy and use scapy.ESP instead of manually generating ESP header. 457*2f2c4c7aSAndroid Build Coastguard Worker inner_pkt = xfrm.EspHdr(spi=TEST_SPI, seqnum=1).Pack() + bytes( 458*2f2c4c7aSAndroid Build Coastguard Worker IpType(src=remoteaddr, dst=myaddr) / 459*2f2c4c7aSAndroid Build Coastguard Worker scapy.UDP(sport=443, dport=32123) / data) + bytes( 460*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base.GetEspTrailer(len(data), {4: IPPROTO_IPIP, 6: IPPROTO_IPV6}[version])) 461*2f2c4c7aSAndroid Build Coastguard Worker input_pkt = (IpType(src=remoteaddr, dst=myaddr) / 462*2f2c4c7aSAndroid Build Coastguard Worker scapy.UDP(sport=4500, dport=encap_port) / 463*2f2c4c7aSAndroid Build Coastguard Worker inner_pkt) 464*2f2c4c7aSAndroid Build Coastguard Worker 465*2f2c4c7aSAndroid Build Coastguard Worker # input_pkt.show2() 466*2f2c4c7aSAndroid Build Coastguard Worker self.ReceivePacketOn(netid, input_pkt) 467*2f2c4c7aSAndroid Build Coastguard Worker 468*2f2c4c7aSAndroid Build Coastguard Worker sainfo = self.xfrm.FindSaInfo(TEST_SPI) 469*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(1, sainfo.curlft.packets) 470*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(datalen + 8, sainfo.curlft.bytes) 471*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(0, sainfo.stats.integrity_failed) 472*2f2c4c7aSAndroid Build Coastguard Worker 473*2f2c4c7aSAndroid Build Coastguard Worker # Uncomment for debugging. 474*2f2c4c7aSAndroid Build Coastguard Worker # subprocess.call("ip -s xfrm state".split()) 475*2f2c4c7aSAndroid Build Coastguard Worker 476*2f2c4c7aSAndroid Build Coastguard Worker encap_sock.close() 477*2f2c4c7aSAndroid Build Coastguard Worker s.close() 478*2f2c4c7aSAndroid Build Coastguard Worker 479*2f2c4c7aSAndroid Build Coastguard Worker def testIPv4UDPEncapRecvTransport(self): 480*2f2c4c7aSAndroid Build Coastguard Worker self._CheckUDPEncapRecv(4, xfrm.XFRM_MODE_TRANSPORT) 481*2f2c4c7aSAndroid Build Coastguard Worker 482*2f2c4c7aSAndroid Build Coastguard Worker def testIPv4UDPEncapRecvTunnel(self): 483*2f2c4c7aSAndroid Build Coastguard Worker self._CheckUDPEncapRecv(4, xfrm.XFRM_MODE_TUNNEL) 484*2f2c4c7aSAndroid Build Coastguard Worker 485*2f2c4c7aSAndroid Build Coastguard Worker # IPv6 UDP encap is broken between: 486*2f2c4c7aSAndroid Build Coastguard Worker # 4db4075f92af ("esp6: fix check on ipv6_skip_exthdr's return value") and 487*2f2c4c7aSAndroid Build Coastguard Worker # 5f9c55c8066b ("ipv6: check return value of ipv6_skip_exthdr") 488*2f2c4c7aSAndroid Build Coastguard Worker @unittest.skipUnless(net_test.KernelAtLeast([(5, 10, 108), (5, 15, 31)]) or 489*2f2c4c7aSAndroid Build Coastguard Worker net_test.NonGXI(5, 10), 490*2f2c4c7aSAndroid Build Coastguard Worker reason="Unsupported or broken on current kernel") 491*2f2c4c7aSAndroid Build Coastguard Worker def testIPv6UDPEncapRecvTransport(self): 492*2f2c4c7aSAndroid Build Coastguard Worker self._CheckUDPEncapRecv(6, xfrm.XFRM_MODE_TRANSPORT) 493*2f2c4c7aSAndroid Build Coastguard Worker 494*2f2c4c7aSAndroid Build Coastguard Worker @unittest.skipUnless(net_test.KernelAtLeast([(5, 10, 108), (5, 15, 31)]) or 495*2f2c4c7aSAndroid Build Coastguard Worker net_test.NonGXI(5, 10), 496*2f2c4c7aSAndroid Build Coastguard Worker reason="Unsupported or broken on current kernel") 497*2f2c4c7aSAndroid Build Coastguard Worker def testIPv6UDPEncapRecvTunnel(self): 498*2f2c4c7aSAndroid Build Coastguard Worker self._CheckUDPEncapRecv(6, xfrm.XFRM_MODE_TUNNEL) 499*2f2c4c7aSAndroid Build Coastguard Worker 500*2f2c4c7aSAndroid Build Coastguard Worker def testAllocSpecificSpi(self): 501*2f2c4c7aSAndroid Build Coastguard Worker spi = 0xABCD 502*2f2c4c7aSAndroid Build Coastguard Worker new_sa = self.xfrm.AllocSpi("::", IPPROTO_ESP, spi, spi) 503*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(spi, new_sa.id.spi) 504*2f2c4c7aSAndroid Build Coastguard Worker 505*2f2c4c7aSAndroid Build Coastguard Worker def testAllocSpecificSpiUnavailable(self): 506*2f2c4c7aSAndroid Build Coastguard Worker """Attempt to allocate the same SPI twice.""" 507*2f2c4c7aSAndroid Build Coastguard Worker spi = 0xABCD 508*2f2c4c7aSAndroid Build Coastguard Worker new_sa = self.xfrm.AllocSpi("::", IPPROTO_ESP, spi, spi) 509*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(spi, new_sa.id.spi) 510*2f2c4c7aSAndroid Build Coastguard Worker with self.assertRaisesErrno(ENOENT): 511*2f2c4c7aSAndroid Build Coastguard Worker new_sa = self.xfrm.AllocSpi("::", IPPROTO_ESP, spi, spi) 512*2f2c4c7aSAndroid Build Coastguard Worker 513*2f2c4c7aSAndroid Build Coastguard Worker def testAllocRangeSpi(self): 514*2f2c4c7aSAndroid Build Coastguard Worker start, end = 0xABCD0, 0xABCDF 515*2f2c4c7aSAndroid Build Coastguard Worker new_sa = self.xfrm.AllocSpi("::", IPPROTO_ESP, start, end) 516*2f2c4c7aSAndroid Build Coastguard Worker spi = new_sa.id.spi 517*2f2c4c7aSAndroid Build Coastguard Worker self.assertGreaterEqual(spi, start) 518*2f2c4c7aSAndroid Build Coastguard Worker self.assertLessEqual(spi, end) 519*2f2c4c7aSAndroid Build Coastguard Worker 520*2f2c4c7aSAndroid Build Coastguard Worker def testAllocRangeSpiUnavailable(self): 521*2f2c4c7aSAndroid Build Coastguard Worker """Attempt to allocate N+1 SPIs from a range of size N.""" 522*2f2c4c7aSAndroid Build Coastguard Worker start, end = 0xABCD0, 0xABCDF 523*2f2c4c7aSAndroid Build Coastguard Worker range_size = end - start + 1 524*2f2c4c7aSAndroid Build Coastguard Worker spis = set() 525*2f2c4c7aSAndroid Build Coastguard Worker # Assert that allocating SPI fails when none are available. 526*2f2c4c7aSAndroid Build Coastguard Worker with self.assertRaisesErrno(ENOENT): 527*2f2c4c7aSAndroid Build Coastguard Worker # Allocating range_size + 1 SPIs is guaranteed to fail. Due to the way 528*2f2c4c7aSAndroid Build Coastguard Worker # kernel picks random SPIs, this has a high probability of failing before 529*2f2c4c7aSAndroid Build Coastguard Worker # reaching that limit. 530*2f2c4c7aSAndroid Build Coastguard Worker for i in range(range_size + 1): 531*2f2c4c7aSAndroid Build Coastguard Worker new_sa = self.xfrm.AllocSpi("::", IPPROTO_ESP, start, end) 532*2f2c4c7aSAndroid Build Coastguard Worker spi = new_sa.id.spi 533*2f2c4c7aSAndroid Build Coastguard Worker self.assertNotIn(spi, spis) 534*2f2c4c7aSAndroid Build Coastguard Worker spis.add(spi) 535*2f2c4c7aSAndroid Build Coastguard Worker 536*2f2c4c7aSAndroid Build Coastguard Worker def testSocketPolicyDstCacheV6(self): 537*2f2c4c7aSAndroid Build Coastguard Worker self._TestSocketPolicyDstCache(6) 538*2f2c4c7aSAndroid Build Coastguard Worker 539*2f2c4c7aSAndroid Build Coastguard Worker def testSocketPolicyDstCacheV4(self): 540*2f2c4c7aSAndroid Build Coastguard Worker self._TestSocketPolicyDstCache(4) 541*2f2c4c7aSAndroid Build Coastguard Worker 542*2f2c4c7aSAndroid Build Coastguard Worker def _TestSocketPolicyDstCache(self, version): 543*2f2c4c7aSAndroid Build Coastguard Worker """Test that destination cache is cleared with socket policy. 544*2f2c4c7aSAndroid Build Coastguard Worker 545*2f2c4c7aSAndroid Build Coastguard Worker This relies on the fact that connect() on a UDP socket populates the 546*2f2c4c7aSAndroid Build Coastguard Worker destination cache. 547*2f2c4c7aSAndroid Build Coastguard Worker """ 548*2f2c4c7aSAndroid Build Coastguard Worker 549*2f2c4c7aSAndroid Build Coastguard Worker # Create UDP socket. 550*2f2c4c7aSAndroid Build Coastguard Worker family = net_test.GetAddressFamily(version) 551*2f2c4c7aSAndroid Build Coastguard Worker netid = self.RandomNetid() 552*2f2c4c7aSAndroid Build Coastguard Worker s = socket(family, SOCK_DGRAM, 0) 553*2f2c4c7aSAndroid Build Coastguard Worker self.SelectInterface(s, netid, "mark") 554*2f2c4c7aSAndroid Build Coastguard Worker 555*2f2c4c7aSAndroid Build Coastguard Worker # Populate the socket's destination cache. 556*2f2c4c7aSAndroid Build Coastguard Worker remote = self.GetRemoteAddress(version) 557*2f2c4c7aSAndroid Build Coastguard Worker s.connect((remote, 53)) 558*2f2c4c7aSAndroid Build Coastguard Worker 559*2f2c4c7aSAndroid Build Coastguard Worker # Apply a policy to the socket. Should clear dst cache. 560*2f2c4c7aSAndroid Build Coastguard Worker reqid = 123 561*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base.ApplySocketPolicy(s, family, xfrm.XFRM_POLICY_OUT, 562*2f2c4c7aSAndroid Build Coastguard Worker TEST_SPI, reqid, None) 563*2f2c4c7aSAndroid Build Coastguard Worker 564*2f2c4c7aSAndroid Build Coastguard Worker # Policy with no matching SA should result in EAGAIN. If destination cache 565*2f2c4c7aSAndroid Build Coastguard Worker # failed to clear, then the UDP packet will be sent normally. 566*2f2c4c7aSAndroid Build Coastguard Worker with self.assertRaisesErrno(EAGAIN): 567*2f2c4c7aSAndroid Build Coastguard Worker s.send(net_test.UDP_PAYLOAD) 568*2f2c4c7aSAndroid Build Coastguard Worker self.ExpectNoPacketsOn(netid, "Packet not blocked by policy") 569*2f2c4c7aSAndroid Build Coastguard Worker s.close() 570*2f2c4c7aSAndroid Build Coastguard Worker 571*2f2c4c7aSAndroid Build Coastguard Worker def _CheckNullEncryptionTunnelMode(self, version): 572*2f2c4c7aSAndroid Build Coastguard Worker family = net_test.GetAddressFamily(version) 573*2f2c4c7aSAndroid Build Coastguard Worker netid = self.RandomNetid() 574*2f2c4c7aSAndroid Build Coastguard Worker local_addr = self.MyAddress(version, netid) 575*2f2c4c7aSAndroid Build Coastguard Worker remote_addr = self.GetRemoteAddress(version) 576*2f2c4c7aSAndroid Build Coastguard Worker 577*2f2c4c7aSAndroid Build Coastguard Worker # Borrow the address of another netId as the source address of the tunnel 578*2f2c4c7aSAndroid Build Coastguard Worker tun_local = self.MyAddress(version, self.RandomNetid(netid)) 579*2f2c4c7aSAndroid Build Coastguard Worker # For generality, pick a tunnel endpoint that's not the address we 580*2f2c4c7aSAndroid Build Coastguard Worker # connect the socket to. 581*2f2c4c7aSAndroid Build Coastguard Worker tun_remote = TUNNEL_ENDPOINTS[version] 582*2f2c4c7aSAndroid Build Coastguard Worker 583*2f2c4c7aSAndroid Build Coastguard Worker # Output 584*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddSaInfo( 585*2f2c4c7aSAndroid Build Coastguard Worker tun_local, tun_remote, 0xABCD, xfrm.XFRM_MODE_TUNNEL, 123, 586*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_CRYPT_NULL, xfrm_base._ALGO_AUTH_NULL, 587*2f2c4c7aSAndroid Build Coastguard Worker None, None, None, netid) 588*2f2c4c7aSAndroid Build Coastguard Worker # Input 589*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddSaInfo( 590*2f2c4c7aSAndroid Build Coastguard Worker tun_remote, tun_local, 0x9876, xfrm.XFRM_MODE_TUNNEL, 456, 591*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_CRYPT_NULL, xfrm_base._ALGO_AUTH_NULL, 592*2f2c4c7aSAndroid Build Coastguard Worker None, None, None, None) 593*2f2c4c7aSAndroid Build Coastguard Worker 594*2f2c4c7aSAndroid Build Coastguard Worker sock = net_test.UDPSocket(family) 595*2f2c4c7aSAndroid Build Coastguard Worker self.SelectInterface(sock, netid, "mark") 596*2f2c4c7aSAndroid Build Coastguard Worker sock.bind((local_addr, 0)) 597*2f2c4c7aSAndroid Build Coastguard Worker local_port = sock.getsockname()[1] 598*2f2c4c7aSAndroid Build Coastguard Worker remote_port = 5555 599*2f2c4c7aSAndroid Build Coastguard Worker 600*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base.ApplySocketPolicy( 601*2f2c4c7aSAndroid Build Coastguard Worker sock, family, xfrm.XFRM_POLICY_OUT, 0xABCD, 123, 602*2f2c4c7aSAndroid Build Coastguard Worker (tun_local, tun_remote)) 603*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base.ApplySocketPolicy( 604*2f2c4c7aSAndroid Build Coastguard Worker sock, family, xfrm.XFRM_POLICY_IN, 0x9876, 456, 605*2f2c4c7aSAndroid Build Coastguard Worker (tun_remote, tun_local)) 606*2f2c4c7aSAndroid Build Coastguard Worker 607*2f2c4c7aSAndroid Build Coastguard Worker # Create and receive an ESP packet. 608*2f2c4c7aSAndroid Build Coastguard Worker IpType = {4: scapy.IP, 6: scapy.IPv6}[version] 609*2f2c4c7aSAndroid Build Coastguard Worker input_pkt = (IpType(src=remote_addr, dst=local_addr) / 610*2f2c4c7aSAndroid Build Coastguard Worker scapy.UDP(sport=remote_port, dport=local_port) / 611*2f2c4c7aSAndroid Build Coastguard Worker b"input hello") 612*2f2c4c7aSAndroid Build Coastguard Worker input_pkt = IpType(bytes(input_pkt)) # Compute length, checksum. 613*2f2c4c7aSAndroid Build Coastguard Worker input_pkt = xfrm_base.EncryptPacketWithNull(input_pkt, 0x9876, 614*2f2c4c7aSAndroid Build Coastguard Worker 1, (tun_remote, tun_local)) 615*2f2c4c7aSAndroid Build Coastguard Worker 616*2f2c4c7aSAndroid Build Coastguard Worker self.ReceivePacketOn(netid, input_pkt) 617*2f2c4c7aSAndroid Build Coastguard Worker msg, addr = sock.recvfrom(1024) 618*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(b"input hello", msg) 619*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual((remote_addr, remote_port), addr[:2]) 620*2f2c4c7aSAndroid Build Coastguard Worker 621*2f2c4c7aSAndroid Build Coastguard Worker # Send and capture a packet. 622*2f2c4c7aSAndroid Build Coastguard Worker sock.sendto(b"output hello", (remote_addr, remote_port)) 623*2f2c4c7aSAndroid Build Coastguard Worker packets = self.ReadAllPacketsOn(netid) 624*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(1, len(packets)) 625*2f2c4c7aSAndroid Build Coastguard Worker output_pkt = packets[0] 626*2f2c4c7aSAndroid Build Coastguard Worker output_pkt, esp_hdr = xfrm_base.DecryptPacketWithNull(output_pkt) 627*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(output_pkt[scapy.UDP].len, len(b"output_hello") + 8) 628*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(remote_addr, output_pkt.dst) 629*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(remote_port, output_pkt[scapy.UDP].dport) 630*2f2c4c7aSAndroid Build Coastguard Worker # length of the payload plus the UDP header 631*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(b"output hello", bytes(output_pkt[scapy.UDP].payload)) 632*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(0xABCD, esp_hdr.spi) 633*2f2c4c7aSAndroid Build Coastguard Worker sock.close() 634*2f2c4c7aSAndroid Build Coastguard Worker 635*2f2c4c7aSAndroid Build Coastguard Worker def testNullEncryptionTunnelMode(self): 636*2f2c4c7aSAndroid Build Coastguard Worker """Verify null encryption in tunnel mode. 637*2f2c4c7aSAndroid Build Coastguard Worker 638*2f2c4c7aSAndroid Build Coastguard Worker This test verifies both manual assembly and disassembly of UDP packets 639*2f2c4c7aSAndroid Build Coastguard Worker with ESP in IPsec tunnel mode. 640*2f2c4c7aSAndroid Build Coastguard Worker """ 641*2f2c4c7aSAndroid Build Coastguard Worker for version in [4, 6]: 642*2f2c4c7aSAndroid Build Coastguard Worker self._CheckNullEncryptionTunnelMode(version) 643*2f2c4c7aSAndroid Build Coastguard Worker 644*2f2c4c7aSAndroid Build Coastguard Worker def _CheckNullEncryptionTransportMode(self, version): 645*2f2c4c7aSAndroid Build Coastguard Worker family = net_test.GetAddressFamily(version) 646*2f2c4c7aSAndroid Build Coastguard Worker netid = self.RandomNetid() 647*2f2c4c7aSAndroid Build Coastguard Worker local_addr = self.MyAddress(version, netid) 648*2f2c4c7aSAndroid Build Coastguard Worker remote_addr = self.GetRemoteAddress(version) 649*2f2c4c7aSAndroid Build Coastguard Worker 650*2f2c4c7aSAndroid Build Coastguard Worker # Output 651*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddSaInfo( 652*2f2c4c7aSAndroid Build Coastguard Worker local_addr, remote_addr, 0xABCD, xfrm.XFRM_MODE_TRANSPORT, 123, 653*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_CRYPT_NULL, xfrm_base._ALGO_AUTH_NULL, 654*2f2c4c7aSAndroid Build Coastguard Worker None, None, None, None) 655*2f2c4c7aSAndroid Build Coastguard Worker # Input 656*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddSaInfo( 657*2f2c4c7aSAndroid Build Coastguard Worker remote_addr, local_addr, 0x9876, xfrm.XFRM_MODE_TRANSPORT, 456, 658*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_CRYPT_NULL, xfrm_base._ALGO_AUTH_NULL, 659*2f2c4c7aSAndroid Build Coastguard Worker None, None, None, None) 660*2f2c4c7aSAndroid Build Coastguard Worker 661*2f2c4c7aSAndroid Build Coastguard Worker sock = net_test.UDPSocket(family) 662*2f2c4c7aSAndroid Build Coastguard Worker self.SelectInterface(sock, netid, "mark") 663*2f2c4c7aSAndroid Build Coastguard Worker sock.bind((local_addr, 0)) 664*2f2c4c7aSAndroid Build Coastguard Worker local_port = sock.getsockname()[1] 665*2f2c4c7aSAndroid Build Coastguard Worker remote_port = 5555 666*2f2c4c7aSAndroid Build Coastguard Worker 667*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base.ApplySocketPolicy( 668*2f2c4c7aSAndroid Build Coastguard Worker sock, family, xfrm.XFRM_POLICY_OUT, 0xABCD, 123, None) 669*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base.ApplySocketPolicy( 670*2f2c4c7aSAndroid Build Coastguard Worker sock, family, xfrm.XFRM_POLICY_IN, 0x9876, 456, None) 671*2f2c4c7aSAndroid Build Coastguard Worker 672*2f2c4c7aSAndroid Build Coastguard Worker # Create and receive an ESP packet. 673*2f2c4c7aSAndroid Build Coastguard Worker IpType = {4: scapy.IP, 6: scapy.IPv6}[version] 674*2f2c4c7aSAndroid Build Coastguard Worker input_pkt = (IpType(src=remote_addr, dst=local_addr) / 675*2f2c4c7aSAndroid Build Coastguard Worker scapy.UDP(sport=remote_port, dport=local_port) / 676*2f2c4c7aSAndroid Build Coastguard Worker b"input hello") 677*2f2c4c7aSAndroid Build Coastguard Worker input_pkt = IpType(bytes(input_pkt)) # Compute length, checksum. 678*2f2c4c7aSAndroid Build Coastguard Worker input_pkt = xfrm_base.EncryptPacketWithNull(input_pkt, 0x9876, 1, None) 679*2f2c4c7aSAndroid Build Coastguard Worker 680*2f2c4c7aSAndroid Build Coastguard Worker self.ReceivePacketOn(netid, input_pkt) 681*2f2c4c7aSAndroid Build Coastguard Worker msg, addr = sock.recvfrom(1024) 682*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(b"input hello", msg) 683*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual((remote_addr, remote_port), addr[:2]) 684*2f2c4c7aSAndroid Build Coastguard Worker 685*2f2c4c7aSAndroid Build Coastguard Worker # Send and capture a packet. 686*2f2c4c7aSAndroid Build Coastguard Worker sock.sendto(b"output hello", (remote_addr, remote_port)) 687*2f2c4c7aSAndroid Build Coastguard Worker packets = self.ReadAllPacketsOn(netid) 688*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(1, len(packets)) 689*2f2c4c7aSAndroid Build Coastguard Worker output_pkt = packets[0] 690*2f2c4c7aSAndroid Build Coastguard Worker output_pkt, esp_hdr = xfrm_base.DecryptPacketWithNull(output_pkt) 691*2f2c4c7aSAndroid Build Coastguard Worker # length of the payload plus the UDP header 692*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(output_pkt[scapy.UDP].len, len(b"output_hello") + 8) 693*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(remote_addr, output_pkt.dst) 694*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(remote_port, output_pkt[scapy.UDP].dport) 695*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(b"output hello", bytes(output_pkt[scapy.UDP].payload)) 696*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(0xABCD, esp_hdr.spi) 697*2f2c4c7aSAndroid Build Coastguard Worker sock.close() 698*2f2c4c7aSAndroid Build Coastguard Worker 699*2f2c4c7aSAndroid Build Coastguard Worker def testNullEncryptionTransportMode(self): 700*2f2c4c7aSAndroid Build Coastguard Worker """Verify null encryption in transport mode. 701*2f2c4c7aSAndroid Build Coastguard Worker 702*2f2c4c7aSAndroid Build Coastguard Worker This test verifies both manual assembly and disassembly of UDP packets 703*2f2c4c7aSAndroid Build Coastguard Worker with ESP in IPsec transport mode. 704*2f2c4c7aSAndroid Build Coastguard Worker """ 705*2f2c4c7aSAndroid Build Coastguard Worker for version in [4, 6]: 706*2f2c4c7aSAndroid Build Coastguard Worker self._CheckNullEncryptionTransportMode(version) 707*2f2c4c7aSAndroid Build Coastguard Worker 708*2f2c4c7aSAndroid Build Coastguard Worker def _CheckGlobalPoliciesByMark(self, version): 709*2f2c4c7aSAndroid Build Coastguard Worker """Tests that global policies may differ by only the mark.""" 710*2f2c4c7aSAndroid Build Coastguard Worker family = net_test.GetAddressFamily(version) 711*2f2c4c7aSAndroid Build Coastguard Worker sel = xfrm.EmptySelector(family) 712*2f2c4c7aSAndroid Build Coastguard Worker # Pick 2 arbitrary mark values. 713*2f2c4c7aSAndroid Build Coastguard Worker mark1 = xfrm.XfrmMark(mark=0xf00, mask=xfrm_base.MARK_MASK_ALL) 714*2f2c4c7aSAndroid Build Coastguard Worker mark2 = xfrm.XfrmMark(mark=0xf00d, mask=xfrm_base.MARK_MASK_ALL) 715*2f2c4c7aSAndroid Build Coastguard Worker # Create a global policy. 716*2f2c4c7aSAndroid Build Coastguard Worker policy = xfrm.UserPolicy(xfrm.XFRM_POLICY_OUT, sel) 717*2f2c4c7aSAndroid Build Coastguard Worker tmpl = xfrm.UserTemplate(AF_UNSPEC, 0xfeed, 0, None) 718*2f2c4c7aSAndroid Build Coastguard Worker # Create the policy with the first mark. 719*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddPolicyInfo(policy, tmpl, mark1) 720*2f2c4c7aSAndroid Build Coastguard Worker # Create the same policy but with the second (different) mark. 721*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddPolicyInfo(policy, tmpl, mark2) 722*2f2c4c7aSAndroid Build Coastguard Worker # Delete the policies individually 723*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.DeletePolicyInfo(sel, xfrm.XFRM_POLICY_OUT, mark1) 724*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.DeletePolicyInfo(sel, xfrm.XFRM_POLICY_OUT, mark2) 725*2f2c4c7aSAndroid Build Coastguard Worker 726*2f2c4c7aSAndroid Build Coastguard Worker def testGlobalPoliciesByMarkV4(self): 727*2f2c4c7aSAndroid Build Coastguard Worker self._CheckGlobalPoliciesByMark(4) 728*2f2c4c7aSAndroid Build Coastguard Worker 729*2f2c4c7aSAndroid Build Coastguard Worker def testGlobalPoliciesByMarkV6(self): 730*2f2c4c7aSAndroid Build Coastguard Worker self._CheckGlobalPoliciesByMark(6) 731*2f2c4c7aSAndroid Build Coastguard Worker 732*2f2c4c7aSAndroid Build Coastguard Worker def _CheckUpdatePolicy(self, version): 733*2f2c4c7aSAndroid Build Coastguard Worker """Tests that we can can update the template on a policy.""" 734*2f2c4c7aSAndroid Build Coastguard Worker family = net_test.GetAddressFamily(version) 735*2f2c4c7aSAndroid Build Coastguard Worker tmpl1 = xfrm.UserTemplate(family, 0xdead, 0, None) 736*2f2c4c7aSAndroid Build Coastguard Worker tmpl2 = xfrm.UserTemplate(family, 0xbeef, 0, None) 737*2f2c4c7aSAndroid Build Coastguard Worker sel = xfrm.EmptySelector(family) 738*2f2c4c7aSAndroid Build Coastguard Worker policy = xfrm.UserPolicy(xfrm.XFRM_POLICY_OUT, sel) 739*2f2c4c7aSAndroid Build Coastguard Worker mark = xfrm.XfrmMark(mark=0xf00, mask=xfrm_base.MARK_MASK_ALL) 740*2f2c4c7aSAndroid Build Coastguard Worker 741*2f2c4c7aSAndroid Build Coastguard Worker def _CheckTemplateMatch(tmpl): 742*2f2c4c7aSAndroid Build Coastguard Worker """Dump the SPD and match a single template on a single policy.""" 743*2f2c4c7aSAndroid Build Coastguard Worker dump = self.xfrm.DumpPolicyInfo() 744*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(1, len(dump)) 745*2f2c4c7aSAndroid Build Coastguard Worker _, attributes = dump[0] 746*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(attributes['XFRMA_TMPL'], tmpl) 747*2f2c4c7aSAndroid Build Coastguard Worker 748*2f2c4c7aSAndroid Build Coastguard Worker # Create a new policy using update. 749*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.UpdatePolicyInfo(policy, tmpl1, mark, None) 750*2f2c4c7aSAndroid Build Coastguard Worker # NEWPOLICY will not update the existing policy. This checks both that 751*2f2c4c7aSAndroid Build Coastguard Worker # UPDPOLICY created a policy and that NEWPOLICY will not perform updates. 752*2f2c4c7aSAndroid Build Coastguard Worker _CheckTemplateMatch(tmpl1) 753*2f2c4c7aSAndroid Build Coastguard Worker with self.assertRaisesErrno(EEXIST): 754*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddPolicyInfo(policy, tmpl2, mark, None) 755*2f2c4c7aSAndroid Build Coastguard Worker # Update the policy using UPDPOLICY. 756*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.UpdatePolicyInfo(policy, tmpl2, mark, None) 757*2f2c4c7aSAndroid Build Coastguard Worker # There should only be one policy after update, and it should have the 758*2f2c4c7aSAndroid Build Coastguard Worker # updated template. 759*2f2c4c7aSAndroid Build Coastguard Worker _CheckTemplateMatch(tmpl2) 760*2f2c4c7aSAndroid Build Coastguard Worker 761*2f2c4c7aSAndroid Build Coastguard Worker def testUpdatePolicyV4(self): 762*2f2c4c7aSAndroid Build Coastguard Worker self._CheckUpdatePolicy(4) 763*2f2c4c7aSAndroid Build Coastguard Worker 764*2f2c4c7aSAndroid Build Coastguard Worker def testUpdatePolicyV6(self): 765*2f2c4c7aSAndroid Build Coastguard Worker self._CheckUpdatePolicy(6) 766*2f2c4c7aSAndroid Build Coastguard Worker 767*2f2c4c7aSAndroid Build Coastguard Worker def _CheckPolicyDifferByDirection(self,version): 768*2f2c4c7aSAndroid Build Coastguard Worker """Tests that policies can differ only by direction.""" 769*2f2c4c7aSAndroid Build Coastguard Worker family = net_test.GetAddressFamily(version) 770*2f2c4c7aSAndroid Build Coastguard Worker tmpl = xfrm.UserTemplate(family, 0xdead, 0, None) 771*2f2c4c7aSAndroid Build Coastguard Worker sel = xfrm.EmptySelector(family) 772*2f2c4c7aSAndroid Build Coastguard Worker mark = xfrm.XfrmMark(mark=0xf00, mask=xfrm_base.MARK_MASK_ALL) 773*2f2c4c7aSAndroid Build Coastguard Worker policy = xfrm.UserPolicy(xfrm.XFRM_POLICY_OUT, sel) 774*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddPolicyInfo(policy, tmpl, mark) 775*2f2c4c7aSAndroid Build Coastguard Worker policy = xfrm.UserPolicy(xfrm.XFRM_POLICY_IN, sel) 776*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddPolicyInfo(policy, tmpl, mark) 777*2f2c4c7aSAndroid Build Coastguard Worker 778*2f2c4c7aSAndroid Build Coastguard Worker def testPolicyDifferByDirectionV4(self): 779*2f2c4c7aSAndroid Build Coastguard Worker self._CheckPolicyDifferByDirection(4) 780*2f2c4c7aSAndroid Build Coastguard Worker 781*2f2c4c7aSAndroid Build Coastguard Worker def testPolicyDifferByDirectionV6(self): 782*2f2c4c7aSAndroid Build Coastguard Worker self._CheckPolicyDifferByDirection(6) 783*2f2c4c7aSAndroid Build Coastguard Worker 784*2f2c4c7aSAndroid Build Coastguard Workerclass XfrmOutputMarkTest(xfrm_base.XfrmLazyTest): 785*2f2c4c7aSAndroid Build Coastguard Worker 786*2f2c4c7aSAndroid Build Coastguard Worker def _CheckTunnelModeOutputMark(self, version, tunsrc, mark, expected_netid): 787*2f2c4c7aSAndroid Build Coastguard Worker """Tests sending UDP packets to tunnel mode SAs with output marks. 788*2f2c4c7aSAndroid Build Coastguard Worker 789*2f2c4c7aSAndroid Build Coastguard Worker Opens a UDP socket and binds it to a random netid, then sets up tunnel mode 790*2f2c4c7aSAndroid Build Coastguard Worker SAs with an output_mark of mark and sets a socket policy to use the SA. 791*2f2c4c7aSAndroid Build Coastguard Worker Then checks that sending on those SAs sends a packet on expected_netid, 792*2f2c4c7aSAndroid Build Coastguard Worker or, if expected_netid is zero, checks that sending returns ENETUNREACH. 793*2f2c4c7aSAndroid Build Coastguard Worker 794*2f2c4c7aSAndroid Build Coastguard Worker Args: 795*2f2c4c7aSAndroid Build Coastguard Worker version: 4 or 6. 796*2f2c4c7aSAndroid Build Coastguard Worker tunsrc: A string, the source address of the tunnel. 797*2f2c4c7aSAndroid Build Coastguard Worker mark: An integer, the output_mark to set in the SA. 798*2f2c4c7aSAndroid Build Coastguard Worker expected_netid: An integer, the netid to expect the kernel to send the 799*2f2c4c7aSAndroid Build Coastguard Worker packet on. If None, expect that sendto will fail with ENETUNREACH. 800*2f2c4c7aSAndroid Build Coastguard Worker """ 801*2f2c4c7aSAndroid Build Coastguard Worker # Open a UDP socket and bind it to a random netid. 802*2f2c4c7aSAndroid Build Coastguard Worker family = net_test.GetAddressFamily(version) 803*2f2c4c7aSAndroid Build Coastguard Worker s = socket(family, SOCK_DGRAM, 0) 804*2f2c4c7aSAndroid Build Coastguard Worker self.SelectInterface(s, self.RandomNetid(), "mark") 805*2f2c4c7aSAndroid Build Coastguard Worker 806*2f2c4c7aSAndroid Build Coastguard Worker # For generality, pick a tunnel endpoint that's not the address we 807*2f2c4c7aSAndroid Build Coastguard Worker # connect the socket to. 808*2f2c4c7aSAndroid Build Coastguard Worker tundst = TUNNEL_ENDPOINTS[version] 809*2f2c4c7aSAndroid Build Coastguard Worker tun_addrs = (tunsrc, tundst) 810*2f2c4c7aSAndroid Build Coastguard Worker 811*2f2c4c7aSAndroid Build Coastguard Worker # Create a tunnel mode SA and use XFRM_OUTPUT_MARK to bind it to netid. 812*2f2c4c7aSAndroid Build Coastguard Worker spi = TEST_SPI * mark 813*2f2c4c7aSAndroid Build Coastguard Worker reqid = 100 + spi 814*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddSaInfo(tunsrc, tundst, spi, xfrm.XFRM_MODE_TUNNEL, reqid, 815*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_CBC_AES_256, xfrm_base._ALGO_HMAC_SHA1, 816*2f2c4c7aSAndroid Build Coastguard Worker None, None, None, mark) 817*2f2c4c7aSAndroid Build Coastguard Worker 818*2f2c4c7aSAndroid Build Coastguard Worker # Set a socket policy to use it. 819*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base.ApplySocketPolicy(s, family, xfrm.XFRM_POLICY_OUT, spi, reqid, 820*2f2c4c7aSAndroid Build Coastguard Worker tun_addrs) 821*2f2c4c7aSAndroid Build Coastguard Worker 822*2f2c4c7aSAndroid Build Coastguard Worker # Send a packet and check that we see it on the wire. 823*2f2c4c7aSAndroid Build Coastguard Worker remoteaddr = self.GetRemoteAddress(version) 824*2f2c4c7aSAndroid Build Coastguard Worker 825*2f2c4c7aSAndroid Build Coastguard Worker packetlen = xfrm_base.GetEspPacketLength(xfrm.XFRM_MODE_TUNNEL, version, 826*2f2c4c7aSAndroid Build Coastguard Worker False, net_test.UDP_PAYLOAD, 827*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_HMAC_SHA1, 828*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_CBC_AES_256) 829*2f2c4c7aSAndroid Build Coastguard Worker 830*2f2c4c7aSAndroid Build Coastguard Worker if expected_netid is not None: 831*2f2c4c7aSAndroid Build Coastguard Worker s.sendto(net_test.UDP_PAYLOAD, (remoteaddr, 53)) 832*2f2c4c7aSAndroid Build Coastguard Worker self._ExpectEspPacketOn(expected_netid, spi, 1, packetlen, tunsrc, tundst) 833*2f2c4c7aSAndroid Build Coastguard Worker else: 834*2f2c4c7aSAndroid Build Coastguard Worker with self.assertRaisesErrno(ENETUNREACH): 835*2f2c4c7aSAndroid Build Coastguard Worker s.sendto(net_test.UDP_PAYLOAD, (remoteaddr, 53)) 836*2f2c4c7aSAndroid Build Coastguard Worker 837*2f2c4c7aSAndroid Build Coastguard Worker s.close() 838*2f2c4c7aSAndroid Build Coastguard Worker 839*2f2c4c7aSAndroid Build Coastguard Worker def testTunnelModeOutputMarkIPv4(self): 840*2f2c4c7aSAndroid Build Coastguard Worker for netid in self.NETIDS: 841*2f2c4c7aSAndroid Build Coastguard Worker tunsrc = self.MyAddress(4, netid) 842*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelModeOutputMark(4, tunsrc, netid, netid) 843*2f2c4c7aSAndroid Build Coastguard Worker 844*2f2c4c7aSAndroid Build Coastguard Worker def testTunnelModeOutputMarkIPv6(self): 845*2f2c4c7aSAndroid Build Coastguard Worker for netid in self.NETIDS: 846*2f2c4c7aSAndroid Build Coastguard Worker tunsrc = self.MyAddress(6, netid) 847*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelModeOutputMark(6, tunsrc, netid, netid) 848*2f2c4c7aSAndroid Build Coastguard Worker 849*2f2c4c7aSAndroid Build Coastguard Worker def testTunnelModeOutputNoMarkIPv4(self): 850*2f2c4c7aSAndroid Build Coastguard Worker tunsrc = self.MyAddress(4, self.RandomNetid()) 851*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelModeOutputMark(4, tunsrc, 0, None) 852*2f2c4c7aSAndroid Build Coastguard Worker 853*2f2c4c7aSAndroid Build Coastguard Worker def testTunnelModeOutputNoMarkIPv6(self): 854*2f2c4c7aSAndroid Build Coastguard Worker tunsrc = self.MyAddress(6, self.RandomNetid()) 855*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelModeOutputMark(6, tunsrc, 0, None) 856*2f2c4c7aSAndroid Build Coastguard Worker 857*2f2c4c7aSAndroid Build Coastguard Worker def testTunnelModeOutputInvalidMarkIPv4(self): 858*2f2c4c7aSAndroid Build Coastguard Worker tunsrc = self.MyAddress(4, self.RandomNetid()) 859*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelModeOutputMark(4, tunsrc, 9999, None) 860*2f2c4c7aSAndroid Build Coastguard Worker 861*2f2c4c7aSAndroid Build Coastguard Worker def testTunnelModeOutputInvalidMarkIPv6(self): 862*2f2c4c7aSAndroid Build Coastguard Worker tunsrc = self.MyAddress(6, self.RandomNetid()) 863*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelModeOutputMark(6, tunsrc, 9999, None) 864*2f2c4c7aSAndroid Build Coastguard Worker 865*2f2c4c7aSAndroid Build Coastguard Worker def testTunnelModeOutputMarkAttributes(self): 866*2f2c4c7aSAndroid Build Coastguard Worker mark = 1234567 867*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddSaInfo(TEST_ADDR1, TUNNEL_ENDPOINTS[6], 0x1234, 868*2f2c4c7aSAndroid Build Coastguard Worker xfrm.XFRM_MODE_TUNNEL, 100, xfrm_base._ALGO_CBC_AES_256, 869*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_HMAC_SHA1, None, None, None, mark) 870*2f2c4c7aSAndroid Build Coastguard Worker dump = self.xfrm.DumpSaInfo() 871*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(1, len(dump)) 872*2f2c4c7aSAndroid Build Coastguard Worker sainfo, attributes = dump[0] 873*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(mark, attributes["XFRMA_OUTPUT_MARK"]) 874*2f2c4c7aSAndroid Build Coastguard Worker 875*2f2c4c7aSAndroid Build Coastguard Worker def testInvalidAlgorithms(self): 876*2f2c4c7aSAndroid Build Coastguard Worker key = binascii.unhexlify("af442892cdcd0ef650e9c299f9a8436a") 877*2f2c4c7aSAndroid Build Coastguard Worker invalid_auth = (xfrm.XfrmAlgoAuth((b"invalid(algo)", 128, 96)), key) 878*2f2c4c7aSAndroid Build Coastguard Worker invalid_crypt = (xfrm.XfrmAlgo((b"invalid(algo)", 128)), key) 879*2f2c4c7aSAndroid Build Coastguard Worker with self.assertRaisesErrno(ENOSYS): 880*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddSaInfo(TEST_ADDR1, TEST_ADDR2, 0x1234, 881*2f2c4c7aSAndroid Build Coastguard Worker xfrm.XFRM_MODE_TRANSPORT, 0, xfrm_base._ALGO_CBC_AES_256, 882*2f2c4c7aSAndroid Build Coastguard Worker invalid_auth, None, None, None, 0) 883*2f2c4c7aSAndroid Build Coastguard Worker with self.assertRaisesErrno(ENOSYS): 884*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddSaInfo(TEST_ADDR1, TEST_ADDR2, 0x1234, 885*2f2c4c7aSAndroid Build Coastguard Worker xfrm.XFRM_MODE_TRANSPORT, 0, invalid_crypt, 886*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_HMAC_SHA1, None, None, None, 0) 887*2f2c4c7aSAndroid Build Coastguard Worker 888*2f2c4c7aSAndroid Build Coastguard Worker def testUpdateSaAddMark(self): 889*2f2c4c7aSAndroid Build Coastguard Worker """Test that an embryonic SA can be updated to add a mark.""" 890*2f2c4c7aSAndroid Build Coastguard Worker for version in [4, 6]: 891*2f2c4c7aSAndroid Build Coastguard Worker spi = 0xABCD 892*2f2c4c7aSAndroid Build Coastguard Worker # Test that an SA created with ALLOCSPI can be updated with the mark. 893*2f2c4c7aSAndroid Build Coastguard Worker new_sa = self.xfrm.AllocSpi(net_test.GetWildcardAddress(version), 894*2f2c4c7aSAndroid Build Coastguard Worker IPPROTO_ESP, spi, spi) 895*2f2c4c7aSAndroid Build Coastguard Worker mark = xfrm.ExactMatchMark(0xf00d) 896*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddSaInfo(net_test.GetWildcardAddress(version), 897*2f2c4c7aSAndroid Build Coastguard Worker net_test.GetWildcardAddress(version), 898*2f2c4c7aSAndroid Build Coastguard Worker spi, xfrm.XFRM_MODE_TUNNEL, 0, 899*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_CBC_AES_256, 900*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_HMAC_SHA1, 901*2f2c4c7aSAndroid Build Coastguard Worker None, None, mark, 0, is_update=True) 902*2f2c4c7aSAndroid Build Coastguard Worker dump = self.xfrm.DumpSaInfo() 903*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(1, len(dump)) # check that update updated 904*2f2c4c7aSAndroid Build Coastguard Worker sainfo, attributes = dump[0] 905*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(mark, attributes["XFRMA_MARK"]) 906*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.DeleteSaInfo(net_test.GetWildcardAddress(version), 907*2f2c4c7aSAndroid Build Coastguard Worker spi, IPPROTO_ESP, mark) 908*2f2c4c7aSAndroid Build Coastguard Worker 909*2f2c4c7aSAndroid Build Coastguard Worker def getXfrmStat(self, statName): 910*2f2c4c7aSAndroid Build Coastguard Worker stateVal = 0 911*2f2c4c7aSAndroid Build Coastguard Worker with open(XFRM_STATS_PROCFILE, 'r') as f: 912*2f2c4c7aSAndroid Build Coastguard Worker for line in f: 913*2f2c4c7aSAndroid Build Coastguard Worker if statName in line: 914*2f2c4c7aSAndroid Build Coastguard Worker stateVal = int(line.split()[1]) 915*2f2c4c7aSAndroid Build Coastguard Worker break 916*2f2c4c7aSAndroid Build Coastguard Worker f.close() 917*2f2c4c7aSAndroid Build Coastguard Worker return stateVal 918*2f2c4c7aSAndroid Build Coastguard Worker 919*2f2c4c7aSAndroid Build Coastguard Worker def testUpdateActiveSaMarks(self): 920*2f2c4c7aSAndroid Build Coastguard Worker """Test that the OUTPUT_MARK can be updated on an ACTIVE SA.""" 921*2f2c4c7aSAndroid Build Coastguard Worker for version in [4, 6]: 922*2f2c4c7aSAndroid Build Coastguard Worker family = net_test.GetAddressFamily(version) 923*2f2c4c7aSAndroid Build Coastguard Worker netid = self.RandomNetid() 924*2f2c4c7aSAndroid Build Coastguard Worker remote = self.GetRemoteAddress(version) 925*2f2c4c7aSAndroid Build Coastguard Worker local = self.MyAddress(version, netid) 926*2f2c4c7aSAndroid Build Coastguard Worker s = socket(family, SOCK_DGRAM, 0) 927*2f2c4c7aSAndroid Build Coastguard Worker self.SelectInterface(s, netid, "mark") 928*2f2c4c7aSAndroid Build Coastguard Worker # Create a mark that we will apply to the policy and later the SA 929*2f2c4c7aSAndroid Build Coastguard Worker mark = xfrm.ExactMatchMark(netid) 930*2f2c4c7aSAndroid Build Coastguard Worker 931*2f2c4c7aSAndroid Build Coastguard Worker # Create a global policy that selects using the mark. 932*2f2c4c7aSAndroid Build Coastguard Worker sel = xfrm.EmptySelector(family) 933*2f2c4c7aSAndroid Build Coastguard Worker policy = xfrm.UserPolicy(xfrm.XFRM_POLICY_OUT, sel) 934*2f2c4c7aSAndroid Build Coastguard Worker tmpl = xfrm.UserTemplate(family, 0, 0, (local, remote)) 935*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddPolicyInfo(policy, tmpl, mark) 936*2f2c4c7aSAndroid Build Coastguard Worker 937*2f2c4c7aSAndroid Build Coastguard Worker # Pull /proc/net/xfrm_stats for baseline 938*2f2c4c7aSAndroid Build Coastguard Worker outNoStateCount = self.getXfrmStat(XFRM_STATS_OUT_NO_STATES); 939*2f2c4c7aSAndroid Build Coastguard Worker 940*2f2c4c7aSAndroid Build Coastguard Worker # should increment XfrmOutNoStates 941*2f2c4c7aSAndroid Build Coastguard Worker s.sendto(net_test.UDP_PAYLOAD, (remote, 53)) 942*2f2c4c7aSAndroid Build Coastguard Worker 943*2f2c4c7aSAndroid Build Coastguard Worker # Check to make sure XfrmOutNoStates is incremented by exactly 1 944*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(outNoStateCount + 1, 945*2f2c4c7aSAndroid Build Coastguard Worker self.getXfrmStat(XFRM_STATS_OUT_NO_STATES)) 946*2f2c4c7aSAndroid Build Coastguard Worker 947*2f2c4c7aSAndroid Build Coastguard Worker length = xfrm_base.GetEspPacketLength(xfrm.XFRM_MODE_TUNNEL, 948*2f2c4c7aSAndroid Build Coastguard Worker version, False, 949*2f2c4c7aSAndroid Build Coastguard Worker net_test.UDP_PAYLOAD, 950*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_HMAC_SHA1, 951*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_CBC_AES_256) 952*2f2c4c7aSAndroid Build Coastguard Worker 953*2f2c4c7aSAndroid Build Coastguard Worker # Add a default SA with no mark that routes to nowhere. 954*2f2c4c7aSAndroid Build Coastguard Worker try: 955*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddSaInfo(local, 956*2f2c4c7aSAndroid Build Coastguard Worker remote, 957*2f2c4c7aSAndroid Build Coastguard Worker TEST_SPI, xfrm.XFRM_MODE_TUNNEL, 0, 958*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_CBC_AES_256, 959*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_HMAC_SHA1, 960*2f2c4c7aSAndroid Build Coastguard Worker None, None, mark, 0, is_update=False) 961*2f2c4c7aSAndroid Build Coastguard Worker except IOError as e: 962*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(EEXIST, e.errno, "SA exists") 963*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddSaInfo(local, 964*2f2c4c7aSAndroid Build Coastguard Worker remote, 965*2f2c4c7aSAndroid Build Coastguard Worker TEST_SPI, xfrm.XFRM_MODE_TUNNEL, 0, 966*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_CBC_AES_256, 967*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_HMAC_SHA1, 968*2f2c4c7aSAndroid Build Coastguard Worker None, None, mark, 0, is_update=True) 969*2f2c4c7aSAndroid Build Coastguard Worker 970*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno( 971*2f2c4c7aSAndroid Build Coastguard Worker ENETUNREACH, 972*2f2c4c7aSAndroid Build Coastguard Worker s.sendto, net_test.UDP_PAYLOAD, (remote, 53)) 973*2f2c4c7aSAndroid Build Coastguard Worker 974*2f2c4c7aSAndroid Build Coastguard Worker # Update the SA to route to a valid netid. 975*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddSaInfo(local, 976*2f2c4c7aSAndroid Build Coastguard Worker remote, 977*2f2c4c7aSAndroid Build Coastguard Worker TEST_SPI, xfrm.XFRM_MODE_TUNNEL, 0, 978*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_CBC_AES_256, 979*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_HMAC_SHA1, 980*2f2c4c7aSAndroid Build Coastguard Worker None, None, mark, netid, is_update=True) 981*2f2c4c7aSAndroid Build Coastguard Worker 982*2f2c4c7aSAndroid Build Coastguard Worker # Now the payload routes to the updated netid. 983*2f2c4c7aSAndroid Build Coastguard Worker s.sendto(net_test.UDP_PAYLOAD, (remote, 53)) 984*2f2c4c7aSAndroid Build Coastguard Worker self._ExpectEspPacketOn(netid, TEST_SPI, 1, length, None, None) 985*2f2c4c7aSAndroid Build Coastguard Worker 986*2f2c4c7aSAndroid Build Coastguard Worker # Get a new netid and reroute the packets to the new netid. 987*2f2c4c7aSAndroid Build Coastguard Worker reroute_netid = self.RandomNetid(netid) 988*2f2c4c7aSAndroid Build Coastguard Worker # Update the SA to change the output mark. 989*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddSaInfo(local, 990*2f2c4c7aSAndroid Build Coastguard Worker remote, 991*2f2c4c7aSAndroid Build Coastguard Worker TEST_SPI, xfrm.XFRM_MODE_TUNNEL, 0, 992*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_CBC_AES_256, 993*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_HMAC_SHA1, 994*2f2c4c7aSAndroid Build Coastguard Worker None, None, mark, reroute_netid, is_update=True) 995*2f2c4c7aSAndroid Build Coastguard Worker 996*2f2c4c7aSAndroid Build Coastguard Worker s.sendto(net_test.UDP_PAYLOAD, (remote, 53)) 997*2f2c4c7aSAndroid Build Coastguard Worker self._ExpectEspPacketOn(reroute_netid, TEST_SPI, 2, length, None, None) 998*2f2c4c7aSAndroid Build Coastguard Worker 999*2f2c4c7aSAndroid Build Coastguard Worker dump = self.xfrm.DumpSaInfo() 1000*2f2c4c7aSAndroid Build Coastguard Worker 1001*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(1, len(dump)) # check that update updated 1002*2f2c4c7aSAndroid Build Coastguard Worker sainfo, attributes = dump[0] 1003*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(reroute_netid, attributes["XFRMA_OUTPUT_MARK"]) 1004*2f2c4c7aSAndroid Build Coastguard Worker 1005*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.DeleteSaInfo(remote, TEST_SPI, IPPROTO_ESP, mark) 1006*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.DeletePolicyInfo(sel, xfrm.XFRM_POLICY_OUT, mark) 1007*2f2c4c7aSAndroid Build Coastguard Worker 1008*2f2c4c7aSAndroid Build Coastguard Worker s.close() 1009*2f2c4c7aSAndroid Build Coastguard Worker 1010*2f2c4c7aSAndroid Build Coastguard Workerif __name__ == "__main__": 1011*2f2c4c7aSAndroid Build Coastguard Worker unittest.main() 1012