1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server; 18 19import static org.junit.Assert.assertEquals; 20import static org.junit.Assert.assertNotNull; 21import static org.junit.Assert.fail; 22import static org.mockito.Matchers.anyInt; 23import static org.mockito.Matchers.anyString; 24import static org.mockito.Matchers.eq; 25import static org.mockito.Mockito.mock; 26import static org.mockito.Mockito.times; 27import static org.mockito.Mockito.verify; 28import static org.mockito.Mockito.when; 29 30import android.app.AppOpsManager; 31import android.content.Context; 32import android.net.INetd; 33import android.net.IpSecAlgorithm; 34import android.net.IpSecConfig; 35import android.net.IpSecManager; 36import android.net.IpSecSpiResponse; 37import android.net.IpSecTransformResponse; 38import android.net.IpSecTunnelInterfaceResponse; 39import android.net.LinkAddress; 40import android.net.Network; 41import android.net.NetworkUtils; 42import android.os.Binder; 43import android.os.ParcelFileDescriptor; 44import android.test.mock.MockContext; 45import android.support.test.filters.SmallTest; 46import android.system.Os; 47 48import java.net.Socket; 49import java.util.Arrays; 50import java.util.Collection; 51 52import org.junit.Before; 53import org.junit.Test; 54import org.junit.runner.RunWith; 55import org.junit.runners.Parameterized; 56 57/** Unit tests for {@link IpSecService}. */ 58@SmallTest 59@RunWith(Parameterized.class) 60public class IpSecServiceParameterizedTest { 61 62 private static final int TEST_SPI = 0xD1201D; 63 64 private final String mDestinationAddr; 65 private final String mSourceAddr; 66 private final LinkAddress mLocalInnerAddress; 67 68 @Parameterized.Parameters 69 public static Collection ipSecConfigs() { 70 return Arrays.asList( 71 new Object[][] { 72 {"1.2.3.4", "8.8.4.4", "10.0.1.1/24"}, 73 {"2601::2", "2601::10", "2001:db8::1/64"} 74 }); 75 } 76 77 private static final byte[] AEAD_KEY = { 78 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 79 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 80 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 81 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 82 0x73, 0x61, 0x6C, 0x74 83 }; 84 private static final byte[] CRYPT_KEY = { 85 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 86 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 87 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 88 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F 89 }; 90 private static final byte[] AUTH_KEY = { 91 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 93 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 94 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F 95 }; 96 97 AppOpsManager mMockAppOps = mock(AppOpsManager.class); 98 99 MockContext mMockContext = new MockContext() { 100 @Override 101 public Object getSystemService(String name) { 102 switch(name) { 103 case Context.APP_OPS_SERVICE: 104 return mMockAppOps; 105 default: 106 return null; 107 } 108 } 109 110 @Override 111 public void enforceCallingOrSelfPermission(String permission, String message) { 112 if (permission == android.Manifest.permission.MANAGE_IPSEC_TUNNELS) { 113 return; 114 } 115 throw new SecurityException("Unavailable permission requested"); 116 } 117 }; 118 119 INetd mMockNetd; 120 IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig; 121 IpSecService mIpSecService; 122 Network fakeNetwork = new Network(0xAB); 123 124 private static final IpSecAlgorithm AUTH_ALGO = 125 new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4); 126 private static final IpSecAlgorithm CRYPT_ALGO = 127 new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); 128 private static final IpSecAlgorithm AEAD_ALGO = 129 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); 130 131 public IpSecServiceParameterizedTest( 132 String sourceAddr, String destAddr, String localInnerAddr) { 133 mSourceAddr = sourceAddr; 134 mDestinationAddr = destAddr; 135 mLocalInnerAddress = new LinkAddress(localInnerAddr); 136 } 137 138 @Before 139 public void setUp() throws Exception { 140 mMockNetd = mock(INetd.class); 141 mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class); 142 mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig); 143 144 // Injecting mock netd 145 when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd); 146 // A package granted the AppOp for MANAGE_IPSEC_TUNNELS will be MODE_ALLOWED. 147 when(mMockAppOps.noteOp(anyInt(), anyInt(), eq("blessedPackage"))) 148 .thenReturn(AppOpsManager.MODE_ALLOWED); 149 // A system package will not be granted the app op, so this should fall back to 150 // a permissions check, which should pass. 151 when(mMockAppOps.noteOp(anyInt(), anyInt(), eq("systemPackage"))) 152 .thenReturn(AppOpsManager.MODE_DEFAULT); 153 // A mismatch between the package name and the UID will return MODE_IGNORED. 154 when(mMockAppOps.noteOp(anyInt(), anyInt(), eq("badPackage"))) 155 .thenReturn(AppOpsManager.MODE_IGNORED); 156 } 157 158 @Test 159 public void testIpSecServiceReserveSpi() throws Exception { 160 when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), eq(mDestinationAddr), eq(TEST_SPI))) 161 .thenReturn(TEST_SPI); 162 163 IpSecSpiResponse spiResp = 164 mIpSecService.allocateSecurityParameterIndex( 165 mDestinationAddr, TEST_SPI, new Binder()); 166 assertEquals(IpSecManager.Status.OK, spiResp.status); 167 assertEquals(TEST_SPI, spiResp.spi); 168 } 169 170 @Test 171 public void testReleaseSecurityParameterIndex() throws Exception { 172 when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), eq(mDestinationAddr), eq(TEST_SPI))) 173 .thenReturn(TEST_SPI); 174 175 IpSecSpiResponse spiResp = 176 mIpSecService.allocateSecurityParameterIndex( 177 mDestinationAddr, TEST_SPI, new Binder()); 178 179 mIpSecService.releaseSecurityParameterIndex(spiResp.resourceId); 180 181 verify(mMockNetd) 182 .ipSecDeleteSecurityAssociation( 183 eq(spiResp.resourceId), 184 anyString(), 185 anyString(), 186 eq(TEST_SPI), 187 anyInt(), 188 anyInt()); 189 190 // Verify quota and RefcountedResource objects cleaned up 191 IpSecService.UserRecord userRecord = 192 mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid()); 193 assertEquals(0, userRecord.mSpiQuotaTracker.mCurrent); 194 try { 195 userRecord.mSpiRecords.getRefcountedResourceOrThrow(spiResp.resourceId); 196 fail("Expected IllegalArgumentException on attempt to access deleted resource"); 197 } catch (IllegalArgumentException expected) { 198 199 } 200 } 201 202 @Test 203 public void testSecurityParameterIndexBinderDeath() throws Exception { 204 when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), eq(mDestinationAddr), eq(TEST_SPI))) 205 .thenReturn(TEST_SPI); 206 207 IpSecSpiResponse spiResp = 208 mIpSecService.allocateSecurityParameterIndex( 209 mDestinationAddr, TEST_SPI, new Binder()); 210 211 IpSecService.UserRecord userRecord = 212 mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid()); 213 IpSecService.RefcountedResource refcountedRecord = 214 userRecord.mSpiRecords.getRefcountedResourceOrThrow(spiResp.resourceId); 215 216 refcountedRecord.binderDied(); 217 218 verify(mMockNetd) 219 .ipSecDeleteSecurityAssociation( 220 eq(spiResp.resourceId), 221 anyString(), 222 anyString(), 223 eq(TEST_SPI), 224 anyInt(), 225 anyInt()); 226 227 // Verify quota and RefcountedResource objects cleaned up 228 assertEquals(0, userRecord.mSpiQuotaTracker.mCurrent); 229 try { 230 userRecord.mSpiRecords.getRefcountedResourceOrThrow(spiResp.resourceId); 231 fail("Expected IllegalArgumentException on attempt to access deleted resource"); 232 } catch (IllegalArgumentException expected) { 233 234 } 235 } 236 237 private int getNewSpiResourceId(String remoteAddress, int returnSpi) throws Exception { 238 when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), anyString(), anyInt())) 239 .thenReturn(returnSpi); 240 241 IpSecSpiResponse spi = 242 mIpSecService.allocateSecurityParameterIndex( 243 NetworkUtils.numericToInetAddress(remoteAddress).getHostAddress(), 244 IpSecManager.INVALID_SECURITY_PARAMETER_INDEX, 245 new Binder()); 246 return spi.resourceId; 247 } 248 249 private void addDefaultSpisAndRemoteAddrToIpSecConfig(IpSecConfig config) throws Exception { 250 config.setSpiResourceId(getNewSpiResourceId(mDestinationAddr, TEST_SPI)); 251 config.setSourceAddress(mSourceAddr); 252 config.setDestinationAddress(mDestinationAddr); 253 } 254 255 private void addAuthAndCryptToIpSecConfig(IpSecConfig config) throws Exception { 256 config.setEncryption(CRYPT_ALGO); 257 config.setAuthentication(AUTH_ALGO); 258 } 259 260 @Test 261 public void testCreateTransform() throws Exception { 262 IpSecConfig ipSecConfig = new IpSecConfig(); 263 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig); 264 addAuthAndCryptToIpSecConfig(ipSecConfig); 265 266 IpSecTransformResponse createTransformResp = 267 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage"); 268 assertEquals(IpSecManager.Status.OK, createTransformResp.status); 269 270 verify(mMockNetd) 271 .ipSecAddSecurityAssociation( 272 eq(createTransformResp.resourceId), 273 anyInt(), 274 anyString(), 275 anyString(), 276 anyInt(), 277 eq(TEST_SPI), 278 anyInt(), 279 anyInt(), 280 eq(IpSecAlgorithm.AUTH_HMAC_SHA256), 281 eq(AUTH_KEY), 282 anyInt(), 283 eq(IpSecAlgorithm.CRYPT_AES_CBC), 284 eq(CRYPT_KEY), 285 anyInt(), 286 eq(""), 287 eq(new byte[] {}), 288 eq(0), 289 anyInt(), 290 anyInt(), 291 anyInt()); 292 } 293 294 @Test 295 public void testCreateTransformAead() throws Exception { 296 IpSecConfig ipSecConfig = new IpSecConfig(); 297 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig); 298 299 ipSecConfig.setAuthenticatedEncryption(AEAD_ALGO); 300 301 IpSecTransformResponse createTransformResp = 302 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage"); 303 assertEquals(IpSecManager.Status.OK, createTransformResp.status); 304 305 verify(mMockNetd) 306 .ipSecAddSecurityAssociation( 307 eq(createTransformResp.resourceId), 308 anyInt(), 309 anyString(), 310 anyString(), 311 anyInt(), 312 eq(TEST_SPI), 313 anyInt(), 314 anyInt(), 315 eq(""), 316 eq(new byte[] {}), 317 eq(0), 318 eq(""), 319 eq(new byte[] {}), 320 eq(0), 321 eq(IpSecAlgorithm.AUTH_CRYPT_AES_GCM), 322 eq(AEAD_KEY), 323 anyInt(), 324 anyInt(), 325 anyInt(), 326 anyInt()); 327 } 328 329 @Test 330 public void testCreateTwoTransformsWithSameSpis() throws Exception { 331 IpSecConfig ipSecConfig = new IpSecConfig(); 332 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig); 333 addAuthAndCryptToIpSecConfig(ipSecConfig); 334 335 IpSecTransformResponse createTransformResp = 336 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage"); 337 assertEquals(IpSecManager.Status.OK, createTransformResp.status); 338 339 // Attempting to create transform a second time with the same SPIs should throw an error... 340 try { 341 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage"); 342 fail("IpSecService should have thrown an error for reuse of SPI"); 343 } catch (IllegalStateException expected) { 344 } 345 346 // ... even if the transform is deleted 347 mIpSecService.deleteTransform(createTransformResp.resourceId); 348 try { 349 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage"); 350 fail("IpSecService should have thrown an error for reuse of SPI"); 351 } catch (IllegalStateException expected) { 352 } 353 } 354 355 @Test 356 public void testReleaseOwnedSpi() throws Exception { 357 IpSecConfig ipSecConfig = new IpSecConfig(); 358 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig); 359 addAuthAndCryptToIpSecConfig(ipSecConfig); 360 361 IpSecTransformResponse createTransformResp = 362 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage"); 363 IpSecService.UserRecord userRecord = 364 mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid()); 365 assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent); 366 mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId()); 367 verify(mMockNetd, times(0)) 368 .ipSecDeleteSecurityAssociation( 369 eq(createTransformResp.resourceId), 370 anyString(), 371 anyString(), 372 eq(TEST_SPI), 373 anyInt(), 374 anyInt()); 375 // quota is not released until the SPI is released by the Transform 376 assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent); 377 } 378 379 @Test 380 public void testDeleteTransform() throws Exception { 381 IpSecConfig ipSecConfig = new IpSecConfig(); 382 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig); 383 addAuthAndCryptToIpSecConfig(ipSecConfig); 384 385 IpSecTransformResponse createTransformResp = 386 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage"); 387 mIpSecService.deleteTransform(createTransformResp.resourceId); 388 389 verify(mMockNetd, times(1)) 390 .ipSecDeleteSecurityAssociation( 391 eq(createTransformResp.resourceId), 392 anyString(), 393 anyString(), 394 eq(TEST_SPI), 395 anyInt(), 396 anyInt()); 397 398 // Verify quota and RefcountedResource objects cleaned up 399 IpSecService.UserRecord userRecord = 400 mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid()); 401 assertEquals(0, userRecord.mTransformQuotaTracker.mCurrent); 402 assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent); 403 404 mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId()); 405 // Verify that ipSecDeleteSa was not called when the SPI was released because the 406 // ownedByTransform property should prevent it; (note, the called count is cumulative). 407 verify(mMockNetd, times(1)) 408 .ipSecDeleteSecurityAssociation( 409 anyInt(), 410 anyString(), 411 anyString(), 412 anyInt(), 413 anyInt(), 414 anyInt()); 415 assertEquals(0, userRecord.mSpiQuotaTracker.mCurrent); 416 417 try { 418 userRecord.mTransformRecords.getRefcountedResourceOrThrow( 419 createTransformResp.resourceId); 420 fail("Expected IllegalArgumentException on attempt to access deleted resource"); 421 } catch (IllegalArgumentException expected) { 422 423 } 424 } 425 426 @Test 427 public void testTransportModeTransformBinderDeath() throws Exception { 428 IpSecConfig ipSecConfig = new IpSecConfig(); 429 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig); 430 addAuthAndCryptToIpSecConfig(ipSecConfig); 431 432 IpSecTransformResponse createTransformResp = 433 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage"); 434 435 IpSecService.UserRecord userRecord = 436 mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid()); 437 IpSecService.RefcountedResource refcountedRecord = 438 userRecord.mTransformRecords.getRefcountedResourceOrThrow( 439 createTransformResp.resourceId); 440 441 refcountedRecord.binderDied(); 442 443 verify(mMockNetd) 444 .ipSecDeleteSecurityAssociation( 445 eq(createTransformResp.resourceId), 446 anyString(), 447 anyString(), 448 eq(TEST_SPI), 449 anyInt(), 450 anyInt()); 451 452 // Verify quota and RefcountedResource objects cleaned up 453 assertEquals(0, userRecord.mTransformQuotaTracker.mCurrent); 454 try { 455 userRecord.mTransformRecords.getRefcountedResourceOrThrow( 456 createTransformResp.resourceId); 457 fail("Expected IllegalArgumentException on attempt to access deleted resource"); 458 } catch (IllegalArgumentException expected) { 459 460 } 461 } 462 463 @Test 464 public void testApplyTransportModeTransform() throws Exception { 465 IpSecConfig ipSecConfig = new IpSecConfig(); 466 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig); 467 addAuthAndCryptToIpSecConfig(ipSecConfig); 468 469 IpSecTransformResponse createTransformResp = 470 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage"); 471 ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket()); 472 473 int resourceId = createTransformResp.resourceId; 474 mIpSecService.applyTransportModeTransform(pfd, IpSecManager.DIRECTION_OUT, resourceId); 475 476 verify(mMockNetd) 477 .ipSecApplyTransportModeTransform( 478 eq(pfd.getFileDescriptor()), 479 eq(resourceId), 480 eq(IpSecManager.DIRECTION_OUT), 481 anyString(), 482 anyString(), 483 eq(TEST_SPI)); 484 } 485 486 @Test 487 public void testRemoveTransportModeTransform() throws Exception { 488 ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket()); 489 mIpSecService.removeTransportModeTransforms(pfd); 490 491 verify(mMockNetd).ipSecRemoveTransportModeTransform(pfd.getFileDescriptor()); 492 } 493 494 private IpSecTunnelInterfaceResponse createAndValidateTunnel( 495 String localAddr, String remoteAddr, String pkgName) { 496 IpSecTunnelInterfaceResponse createTunnelResp = 497 mIpSecService.createTunnelInterface( 498 mSourceAddr, mDestinationAddr, fakeNetwork, new Binder(), pkgName); 499 500 assertNotNull(createTunnelResp); 501 assertEquals(IpSecManager.Status.OK, createTunnelResp.status); 502 return createTunnelResp; 503 } 504 505 @Test 506 public void testCreateTunnelInterface() throws Exception { 507 IpSecTunnelInterfaceResponse createTunnelResp = 508 createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage"); 509 510 // Check that we have stored the tracking object, and retrieve it 511 IpSecService.UserRecord userRecord = 512 mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid()); 513 IpSecService.RefcountedResource refcountedRecord = 514 userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow( 515 createTunnelResp.resourceId); 516 517 assertEquals(1, userRecord.mTunnelQuotaTracker.mCurrent); 518 verify(mMockNetd) 519 .addVirtualTunnelInterface( 520 eq(createTunnelResp.interfaceName), 521 eq(mSourceAddr), 522 eq(mDestinationAddr), 523 anyInt(), 524 anyInt()); 525 } 526 527 @Test 528 public void testDeleteTunnelInterface() throws Exception { 529 IpSecTunnelInterfaceResponse createTunnelResp = 530 createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage"); 531 532 IpSecService.UserRecord userRecord = 533 mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid()); 534 535 mIpSecService.deleteTunnelInterface(createTunnelResp.resourceId, "blessedPackage"); 536 537 // Verify quota and RefcountedResource objects cleaned up 538 assertEquals(0, userRecord.mTunnelQuotaTracker.mCurrent); 539 verify(mMockNetd).removeVirtualTunnelInterface(eq(createTunnelResp.interfaceName)); 540 try { 541 userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow( 542 createTunnelResp.resourceId); 543 fail("Expected IllegalArgumentException on attempt to access deleted resource"); 544 } catch (IllegalArgumentException expected) { 545 } 546 } 547 548 @Test 549 public void testTunnelInterfaceBinderDeath() throws Exception { 550 IpSecTunnelInterfaceResponse createTunnelResp = 551 createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage"); 552 553 IpSecService.UserRecord userRecord = 554 mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid()); 555 IpSecService.RefcountedResource refcountedRecord = 556 userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow( 557 createTunnelResp.resourceId); 558 559 refcountedRecord.binderDied(); 560 561 // Verify quota and RefcountedResource objects cleaned up 562 assertEquals(0, userRecord.mTunnelQuotaTracker.mCurrent); 563 verify(mMockNetd).removeVirtualTunnelInterface(eq(createTunnelResp.interfaceName)); 564 try { 565 userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow( 566 createTunnelResp.resourceId); 567 fail("Expected IllegalArgumentException on attempt to access deleted resource"); 568 } catch (IllegalArgumentException expected) { 569 } 570 } 571 572 @Test 573 public void testAddRemoveAddressFromTunnelInterface() throws Exception { 574 for (String pkgName : new String[]{"blessedPackage", "systemPackage"}) { 575 IpSecTunnelInterfaceResponse createTunnelResp = 576 createAndValidateTunnel(mSourceAddr, mDestinationAddr, pkgName); 577 mIpSecService.addAddressToTunnelInterface( 578 createTunnelResp.resourceId, mLocalInnerAddress, pkgName); 579 verify(mMockNetd, times(1)) 580 .interfaceAddAddress( 581 eq(createTunnelResp.interfaceName), 582 eq(mLocalInnerAddress.getAddress().getHostAddress()), 583 eq(mLocalInnerAddress.getPrefixLength())); 584 mIpSecService.removeAddressFromTunnelInterface( 585 createTunnelResp.resourceId, mLocalInnerAddress, pkgName); 586 verify(mMockNetd, times(1)) 587 .interfaceDelAddress( 588 eq(createTunnelResp.interfaceName), 589 eq(mLocalInnerAddress.getAddress().getHostAddress()), 590 eq(mLocalInnerAddress.getPrefixLength())); 591 mIpSecService.deleteTunnelInterface(createTunnelResp.resourceId, pkgName); 592 } 593 } 594 595 @Test 596 public void testAddTunnelFailsForBadPackageName() throws Exception { 597 try { 598 IpSecTunnelInterfaceResponse createTunnelResp = 599 createAndValidateTunnel(mSourceAddr, mDestinationAddr, "badPackage"); 600 fail("Expected a SecurityException for badPackage."); 601 } catch (SecurityException expected) { 602 } 603 } 604} 605