From 69eb8325c0c403e28fb938112a3077d381207a8e Mon Sep 17 00:00:00 2001 From: Yan Yan <evitayan@google.com> Date: Tue, 12 Dec 2023 21:53:46 +0000 Subject: [PATCH] Revert "Support getting transform state in IpSecService" This reverts commit ab5006c17d417570b386d46e369916ea3be1d0c1. Reason for revert: b/316010034 breaking VCN unit tests Change-Id: I68cb1a99bb6e492c16901972d201761cd00df6fa --- .../src/android/net/IIpSecService.aidl | 3 - framework-t/src/android/net/IpSecManager.java | 13 - .../src/android/net/IpSecTransform.java | 44 --- .../src/android/net/IpSecTransformState.aidl | 20 -- .../src/android/net/IpSecTransformState.java | 302 ------------------ .../src/com/android/server/IpSecService.java | 51 --- .../server/IpSecServiceParameterizedTest.java | 33 -- 7 files changed, 466 deletions(-) delete mode 100644 framework-t/src/android/net/IpSecTransformState.aidl delete mode 100644 framework-t/src/android/net/IpSecTransformState.java diff --git a/framework-t/src/android/net/IIpSecService.aidl b/framework-t/src/android/net/IIpSecService.aidl index f972ab9d2e..88ffd0ea9e 100644 --- a/framework-t/src/android/net/IIpSecService.aidl +++ b/framework-t/src/android/net/IIpSecService.aidl @@ -22,7 +22,6 @@ import android.net.IpSecConfig; import android.net.IpSecUdpEncapResponse; import android.net.IpSecSpiResponse; import android.net.IpSecTransformResponse; -import android.net.IpSecTransformState; import android.net.IpSecTunnelInterfaceResponse; import android.os.Bundle; import android.os.IBinder; @@ -75,8 +74,6 @@ interface IIpSecService void deleteTransform(int transformId); - IpSecTransformState getTransformState(int transformId); - void applyTransportModeTransform( in ParcelFileDescriptor socket, int direction, int transformId); diff --git a/framework-t/src/android/net/IpSecManager.java b/framework-t/src/android/net/IpSecManager.java index 3f74e1c3cb..3afa6ef60f 100644 --- a/framework-t/src/android/net/IpSecManager.java +++ b/framework-t/src/android/net/IpSecManager.java @@ -65,13 +65,6 @@ import java.util.Objects; public class IpSecManager { private static final String TAG = "IpSecManager"; - // TODO : remove this class when udc-mainline-prod is abandoned and android.net.flags.Flags is - // available here - /** @hide */ - public static class Flags { - static final String IPSEC_TRANSFORM_STATE = "com.android.net.flags.ipsec_transform_state"; - } - /** * Feature flag to declare the kernel support of updating IPsec SAs. * @@ -1091,12 +1084,6 @@ public class IpSecManager { } } - /** @hide */ - public IpSecTransformState getTransformState(int transformId) - throws IllegalStateException, RemoteException { - return mService.getTransformState(transformId); - } - /** * Construct an instance of IpSecManager within an application context. * diff --git a/framework-t/src/android/net/IpSecTransform.java b/framework-t/src/android/net/IpSecTransform.java index 0412a76dbe..c236b6cb3a 100644 --- a/framework-t/src/android/net/IpSecTransform.java +++ b/framework-t/src/android/net/IpSecTransform.java @@ -15,11 +15,8 @@ */ package android.net; -import static android.net.IpSecManager.Flags.IPSEC_TRANSFORM_STATE; import static android.net.IpSecManager.INVALID_RESOURCE_ID; -import android.annotation.CallbackExecutor; -import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -29,8 +26,6 @@ import android.annotation.SystemApi; import android.content.Context; import android.content.pm.PackageManager; import android.os.Binder; -import android.os.OutcomeReceiver; -import android.os.RemoteException; import android.os.ServiceSpecificException; import android.util.Log; @@ -43,7 +38,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.net.InetAddress; import java.util.Objects; -import java.util.concurrent.Executor; /** * This class represents a transform, which roughly corresponds to an IPsec Security Association. @@ -206,44 +200,6 @@ public final class IpSecTransform implements AutoCloseable { return mResourceId; } - /** - * Retrieve the current state of this IpSecTransform. - * - * @param executor The {@link Executor} on which to call the supplied callback. - * @param callback Callback that's called after the transform state is ready or when an error - * occurs. - * @see IpSecTransformState - * @hide - */ - @FlaggedApi(IPSEC_TRANSFORM_STATE) - public void getIpSecTransformState( - @CallbackExecutor @NonNull Executor executor, - @NonNull OutcomeReceiver<IpSecTransformState, RuntimeException> callback) { - Objects.requireNonNull(executor); - Objects.requireNonNull(callback); - - // TODO: Consider adding check to prevent DDoS attack. - - try { - final IpSecTransformState ipSecTransformState = - getIpSecManager(mContext).getTransformState(mResourceId); - executor.execute( - () -> { - callback.onResult(ipSecTransformState); - }); - } catch (IllegalStateException e) { - executor.execute( - () -> { - callback.onError(e); - }); - } catch (RemoteException e) { - executor.execute( - () -> { - callback.onError(e.rethrowFromSystemServer()); - }); - } - } - /** * A callback class to provide status information regarding a NAT-T keepalive session * diff --git a/framework-t/src/android/net/IpSecTransformState.aidl b/framework-t/src/android/net/IpSecTransformState.aidl deleted file mode 100644 index 69cce28ee7..0000000000 --- a/framework-t/src/android/net/IpSecTransformState.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -/** @hide */ -parcelable IpSecTransformState; \ No newline at end of file diff --git a/framework-t/src/android/net/IpSecTransformState.java b/framework-t/src/android/net/IpSecTransformState.java deleted file mode 100644 index daebbc429c..0000000000 --- a/framework-t/src/android/net/IpSecTransformState.java +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.net; - -import static android.net.IpSecManager.Flags.IPSEC_TRANSFORM_STATE; - -import static com.android.internal.annotations.VisibleForTesting.Visibility; - -import android.annotation.FlaggedApi; -import android.annotation.NonNull; -import android.os.Parcel; -import android.os.Parcelable; - -import com.android.internal.annotations.VisibleForTesting; -import com.android.net.module.util.HexDump; - -import java.util.Objects; - -/** - * This class represents a snapshot of the state of an IpSecTransform - * - * <p>This class provides the current state of an IpSecTransform, enabling link metric analysis by - * the caller. Use cases include understanding transform usage, such as packet and byte counts, as - * well as observing out-of-order delivery by checking the bitmap. Additionally, callers can query - * IpSecTransformStates at two timestamps. By comparing the changes in packet counts and sequence - * numbers, callers can estimate IPsec data loss in the inbound direction. - * - * @hide - */ -@FlaggedApi(IPSEC_TRANSFORM_STATE) -public final class IpSecTransformState implements Parcelable { - private final long mTimeStamp; - private final long mTxHighestSequenceNumber; - private final long mRxHighestSequenceNumber; - private final long mPacketCount; - private final long mByteCount; - private final byte[] mReplayBitmap; - - private IpSecTransformState( - long timestamp, - long txHighestSequenceNumber, - long rxHighestSequenceNumber, - long packetCount, - long byteCount, - byte[] replayBitmap) { - mTimeStamp = timestamp; - mTxHighestSequenceNumber = txHighestSequenceNumber; - mRxHighestSequenceNumber = rxHighestSequenceNumber; - mPacketCount = packetCount; - mByteCount = byteCount; - - Objects.requireNonNull(replayBitmap, "replayBitmap is null"); - mReplayBitmap = replayBitmap.clone(); - - validate(); - } - - private void validate() { - Objects.requireNonNull(mReplayBitmap, "mReplayBitmap is null"); - } - - /** - * Deserializes a IpSecTransformState from a PersistableBundle. - * - * @hide - */ - @VisibleForTesting(visibility = Visibility.PRIVATE) - public IpSecTransformState(@NonNull Parcel in) { - Objects.requireNonNull(in, "The input PersistableBundle is null"); - mTimeStamp = in.readLong(); - mTxHighestSequenceNumber = in.readLong(); - mRxHighestSequenceNumber = in.readLong(); - mPacketCount = in.readLong(); - mByteCount = in.readLong(); - mReplayBitmap = HexDump.hexStringToByteArray(in.readString()); - - validate(); - } - - // Parcelable methods - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@NonNull Parcel out, int flags) { - out.writeLong(mTimeStamp); - out.writeLong(mTxHighestSequenceNumber); - out.writeLong(mRxHighestSequenceNumber); - out.writeLong(mPacketCount); - out.writeLong(mByteCount); - out.writeString(HexDump.toHexString(mReplayBitmap)); - } - - @NonNull - public static final Parcelable.Creator<IpSecTransformState> CREATOR = - new Parcelable.Creator<IpSecTransformState>() { - @NonNull - public IpSecTransformState createFromParcel(Parcel in) { - return new IpSecTransformState(in); - } - - @NonNull - public IpSecTransformState[] newArray(int size) { - return new IpSecTransformState[size]; - } - }; - - /** - * Retrieve the epoch timestamp (milliseconds) for when this state was created - * - * @see Builder#setTimestamp(long) - * @hide - */ - public long getTimestamp() { - return mTimeStamp; - } - - /** - * Retrieve the highest sequence number sent so far - * - * @see Builder#setTxHighestSequenceNumber(long) - * @hide - */ - public long getTxHighestSequenceNumber() { - return mTxHighestSequenceNumber; - } - - /** - * Retrieve the highest sequence number received so far - * - * @see Builder#setRxHighestSequenceNumber(long) - * @hide - */ - public long getRxHighestSequenceNumber() { - return mRxHighestSequenceNumber; - } - - /** - * Retrieve the number of packets received AND sent so far - * - * @see Builder#setPacketCount(long) - * @hide - */ - public long getPacketCount() { - return mPacketCount; - } - - /** - * Retrieve the number of bytes received AND sent so far - * - * @see Builder#setByteCount(long) - * @hide - */ - public long getByteCount() { - return mByteCount; - } - - /** - * Retrieve the replay bitmap - * - * <p>This bitmap represents a replay window, allowing the caller to observe out-of-order - * delivery. The last bit represents the highest sequence number received so far and bits for - * the received packets will be marked as true. - * - * <p>The size of a replay bitmap will never change over the lifetime of an IpSecTransform - * - * <p>The replay bitmap is solely useful for inbound IpSecTransforms. For outbound - * IpSecTransforms, all bits will be unchecked. - * - * @see Builder#setReplayBitmap(byte[]) - * @hide - */ - @NonNull - public byte[] getReplayBitmap() { - return mReplayBitmap.clone(); - } - - /** - * Builder class for testing purposes - * - * @hide - */ - @FlaggedApi(IPSEC_TRANSFORM_STATE) - public static final class Builder { - private long mTimeStamp; - private long mTxHighestSequenceNumber; - private long mRxHighestSequenceNumber; - private long mPacketCount; - private long mByteCount; - private byte[] mReplayBitmap; - - /** @hide */ - public Builder() { - mTimeStamp = System.currentTimeMillis(); - } - - /** - * Set the epoch timestamp (milliseconds) for when this state was created - * - * @see IpSecTransformState#getTimestamp() - * @hide - */ - @NonNull - public Builder setTimestamp(long timeStamp) { - mTimeStamp = timeStamp; - return this; - } - - /** - * Set the highest sequence number sent so far - * - * @see IpSecTransformState#getTxHighestSequenceNumber() - * @hide - */ - @NonNull - public Builder setTxHighestSequenceNumber(long seqNum) { - mTxHighestSequenceNumber = seqNum; - return this; - } - - /** - * Set the highest sequence number received so far - * - * @see IpSecTransformState#getRxHighestSequenceNumber() - * @hide - */ - @NonNull - public Builder setRxHighestSequenceNumber(long seqNum) { - mRxHighestSequenceNumber = seqNum; - return this; - } - - /** - * Set the number of packets received AND sent so far - * - * @see IpSecTransformState#getPacketCount() - * @hide - */ - @NonNull - public Builder setPacketCount(long packetCount) { - mPacketCount = packetCount; - return this; - } - - /** - * Set the number of bytes received AND sent so far - * - * @see IpSecTransformState#getByteCount() - * @hide - */ - @NonNull - public Builder setByteCount(long byteCount) { - mByteCount = byteCount; - return this; - } - - /** - * Set the replay bitmap - * - * @see IpSecTransformState#getReplayBitmap() - * @hide - */ - @NonNull - public Builder setReplayBitmap(@NonNull byte[] bitMap) { - mReplayBitmap = bitMap.clone(); - return this; - } - - /** - * Build and validate the IpSecTransformState - * - * @return an immutable IpSecTransformState instance - * @hide - */ - @NonNull - public IpSecTransformState build() { - return new IpSecTransformState( - mTimeStamp, - mTxHighestSequenceNumber, - mRxHighestSequenceNumber, - mPacketCount, - mByteCount, - mReplayBitmap); - } - } -} diff --git a/service-t/src/com/android/server/IpSecService.java b/service-t/src/com/android/server/IpSecService.java index ea91e6471c..a884840b77 100644 --- a/service-t/src/com/android/server/IpSecService.java +++ b/service-t/src/com/android/server/IpSecService.java @@ -42,7 +42,6 @@ import android.net.IpSecMigrateInfoParcel; import android.net.IpSecSpiResponse; import android.net.IpSecTransform; import android.net.IpSecTransformResponse; -import android.net.IpSecTransformState; import android.net.IpSecTunnelInterfaceResponse; import android.net.IpSecUdpEncapResponse; import android.net.LinkAddress; @@ -71,7 +70,6 @@ import com.android.modules.utils.build.SdkLevel; import com.android.net.module.util.BinderUtils; import com.android.net.module.util.NetdUtils; import com.android.net.module.util.PermissionUtils; -import com.android.net.module.util.netlink.xfrm.XfrmNetlinkNewSaMessage; import libcore.io.IoUtils; @@ -111,7 +109,6 @@ public class IpSecService extends IIpSecService.Stub { @VisibleForTesting static final int MAX_PORT_BIND_ATTEMPTS = 10; private final INetd mNetd; - private final IpSecXfrmController mIpSecXfrmCtrl; static { try { @@ -155,11 +152,6 @@ public class IpSecService extends IIpSecService.Stub { } return netd; } - - /** Get a instance of IpSecXfrmController */ - public IpSecXfrmController getIpSecXfrmController() { - return new IpSecXfrmController(); - } } final UidFdTagger mUidFdTagger; @@ -1119,7 +1111,6 @@ public class IpSecService extends IIpSecService.Stub { mContext = context; mDeps = Objects.requireNonNull(deps, "Missing dependencies."); mUidFdTagger = uidFdTagger; - mIpSecXfrmCtrl = mDeps.getIpSecXfrmController(); try { mNetd = mDeps.getNetdInstance(mContext); } catch (RemoteException e) { @@ -1871,48 +1862,6 @@ public class IpSecService extends IIpSecService.Stub { releaseResource(userRecord.mTransformRecords, resourceId); } - @Override - public synchronized IpSecTransformState getTransformState(int transformId) - throws IllegalStateException, RemoteException { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.ACCESS_NETWORK_STATE, "IpsecService#getTransformState"); - - UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid()); - TransformRecord transformInfo = - userRecord.mTransformRecords.getResourceOrThrow(transformId); - - final int spi = transformInfo.getSpiRecord().getSpi(); - final InetAddress destAddress = - InetAddresses.parseNumericAddress( - transformInfo.getConfig().getDestinationAddress()); - Log.d(TAG, "getTransformState for spi " + spi + " destAddress " + destAddress); - - // Make netlink call - final XfrmNetlinkNewSaMessage xfrmNewSaMsg; - try { - xfrmNewSaMsg = mIpSecXfrmCtrl.ipSecGetSa(destAddress, Integer.toUnsignedLong(spi)); - } catch (ErrnoException | IOException e) { - Log.e(TAG, "getTransformState: failed to get IpSecTransformState" + e.toString()); - throw new IllegalStateException("Failed to get IpSecTransformState", e); - } - - // Keep the netlink socket open to save time for the next call. It is cheap to have a - // persistent netlink socket in the system server - - if (xfrmNewSaMsg == null) { - Log.e(TAG, "getTransformState: failed to get IpSecTransformState xfrmNewSaMsg is null"); - throw new IllegalStateException("Failed to get IpSecTransformState"); - } - - return new IpSecTransformState.Builder() - .setTxHighestSequenceNumber(xfrmNewSaMsg.getTxSequenceNumber()) - .setRxHighestSequenceNumber(xfrmNewSaMsg.getRxSequenceNumber()) - .setPacketCount(xfrmNewSaMsg.getPacketCount()) - .setByteCount(xfrmNewSaMsg.getByteCount()) - .setReplayBitmap(xfrmNewSaMsg.getBitmap()) - .build(); - } - /** * Apply an active transport mode transform to a socket, which will apply the IPsec security * association as a correspondent policy to the provided socket diff --git a/tests/unit/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/unit/java/com/android/server/IpSecServiceParameterizedTest.java index 8037542ae4..1618a62c81 100644 --- a/tests/unit/java/com/android/server/IpSecServiceParameterizedTest.java +++ b/tests/unit/java/com/android/server/IpSecServiceParameterizedTest.java @@ -33,7 +33,6 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; @@ -75,7 +74,6 @@ import android.util.ArraySet; import androidx.test.filters.SmallTest; -import com.android.net.module.util.netlink.xfrm.XfrmNetlinkNewSaMessage; import com.android.server.IpSecService.TunnelInterfaceRecord; import com.android.testutils.DevSdkIgnoreRule; @@ -87,7 +85,6 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import java.net.Inet4Address; -import java.net.InetAddress; import java.net.Socket; import java.util.Arrays; import java.util.Collection; @@ -152,7 +149,6 @@ public class IpSecServiceParameterizedTest { private Set<String> mAllowedPermissions = new ArraySet<>(Arrays.asList( android.Manifest.permission.MANAGE_IPSEC_TUNNELS, android.Manifest.permission.NETWORK_STACK, - android.Manifest.permission.ACCESS_NETWORK_STATE, PERMISSION_MAINLINE_NETWORK_STACK)); private void setAllowedPermissions(String... permissions) { @@ -206,13 +202,11 @@ public class IpSecServiceParameterizedTest { private IpSecService.Dependencies makeDependencies() throws RemoteException { final IpSecService.Dependencies deps = mock(IpSecService.Dependencies.class); when(deps.getNetdInstance(mTestContext)).thenReturn(mMockNetd); - when(deps.getIpSecXfrmController()).thenReturn(mMockXfrmCtrl); return deps; } INetd mMockNetd; PackageManager mMockPkgMgr; - IpSecXfrmController mMockXfrmCtrl; IpSecService.Dependencies mDeps; IpSecService mIpSecService; Network fakeNetwork = new Network(0xAB); @@ -241,7 +235,6 @@ public class IpSecServiceParameterizedTest { @Before public void setUp() throws Exception { mMockNetd = mock(INetd.class); - mMockXfrmCtrl = mock(IpSecXfrmController.class); mMockPkgMgr = mock(PackageManager.class); mDeps = makeDependencies(); mIpSecService = new IpSecService(mTestContext, mDeps); @@ -512,32 +505,6 @@ public class IpSecServiceParameterizedTest { } } - @Test - public void getTransformState() throws Exception { - XfrmNetlinkNewSaMessage mockXfrmNewSaMsg = mock(XfrmNetlinkNewSaMessage.class); - when(mockXfrmNewSaMsg.getBitmap()).thenReturn(new byte[512]); - when(mMockXfrmCtrl.ipSecGetSa(any(InetAddress.class), anyLong())) - .thenReturn(mockXfrmNewSaMsg); - - // Create transform - IpSecConfig ipSecConfig = new IpSecConfig(); - addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig); - addAuthAndCryptToIpSecConfig(ipSecConfig); - - IpSecTransformResponse createTransformResp = - mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE); - assertEquals(IpSecManager.Status.OK, createTransformResp.status); - - // Get transform state - mIpSecService.getTransformState(createTransformResp.resourceId); - - // Verifications - verify(mMockXfrmCtrl) - .ipSecGetSa( - eq(InetAddresses.parseNumericAddress(mDestinationAddr)), - eq(Integer.toUnsignedLong(TEST_SPI))); - } - @Test public void testReleaseOwnedSpi() throws Exception { IpSecConfig ipSecConfig = new IpSecConfig(); -- GitLab