diff options
| -rw-r--r-- | core/java/android/net/vcn/VcnTransportInfo.java | 100 | ||||
| -rw-r--r-- | tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java | 41 |
2 files changed, 129 insertions, 12 deletions
diff --git a/core/java/android/net/vcn/VcnTransportInfo.java b/core/java/android/net/vcn/VcnTransportInfo.java index 4d8cf91621ba..0e9ccf144c2e 100644 --- a/core/java/android/net/vcn/VcnTransportInfo.java +++ b/core/java/android/net/vcn/VcnTransportInfo.java @@ -16,14 +16,23 @@ package android.net.vcn; +import static android.net.NetworkCapabilities.REDACT_ALL; +import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS; +import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; + +import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE; + import android.annotation.NonNull; import android.annotation.Nullable; +import android.net.NetworkCapabilities; import android.net.TransportInfo; import android.net.wifi.WifiInfo; import android.os.Parcel; import android.os.Parcelable; import android.telephony.SubscriptionManager; +import com.android.internal.annotations.VisibleForTesting; + import java.util.Objects; /** @@ -37,28 +46,41 @@ import java.util.Objects; * SubscriptionManager#INVALID_SUBSCRIPTION_ID}. If the underlying Network is Cellular, the WifiInfo * will be {@code null}. * + * <p>Receipt of a VcnTransportInfo requires the NETWORK_SETTINGS permission; else the entire + * VcnTransportInfo instance will be redacted. + * * @hide */ public class VcnTransportInfo implements TransportInfo, Parcelable { @Nullable private final WifiInfo mWifiInfo; private final int mSubId; + /** + * The redaction scheme to use when parcelling. + * + * <p>The TransportInfo/NetworkCapabilities redaction mechanisms rely on redaction being + * performed at parcelling time. This means that the redaction scheme must be stored for later + * use. + * + * <p>Since the redaction scheme itself is not parcelled, this field is listed as a transient. + * + * <p>Defaults to REDACT_ALL when constructed using public constructors, or creating from + * parcels. + */ + private final transient long mRedactions; + public VcnTransportInfo(@NonNull WifiInfo wifiInfo) { - this(wifiInfo, SubscriptionManager.INVALID_SUBSCRIPTION_ID); + this(wifiInfo, INVALID_SUBSCRIPTION_ID, REDACT_ALL); } public VcnTransportInfo(int subId) { - this(null /* wifiInfo */, subId); + this(null /* wifiInfo */, subId, REDACT_ALL); } - private VcnTransportInfo(@Nullable WifiInfo wifiInfo, int subId) { - if (wifiInfo == null && subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { - throw new IllegalArgumentException( - "VcnTransportInfo requires either non-null WifiInfo or valid subId"); - } - + private VcnTransportInfo(@Nullable WifiInfo wifiInfo, int subId, long redactions) { mWifiInfo = wifiInfo; mSubId = subId; + mRedactions = redactions; } /** @@ -86,8 +108,19 @@ public class VcnTransportInfo implements TransportInfo, Parcelable { return mSubId; } + /** + * Gets the redaction scheme + * + * @hide + */ + @VisibleForTesting(visibility = PRIVATE) + public long getRedaction() { + return mRedactions; + } + @Override public int hashCode() { + // mRedactions not hashed, as it is a transient, for control of parcelling return Objects.hash(mWifiInfo, mSubId); } @@ -96,6 +129,7 @@ public class VcnTransportInfo implements TransportInfo, Parcelable { if (!(o instanceof VcnTransportInfo)) return false; final VcnTransportInfo that = (VcnTransportInfo) o; + // mRedactions not compared, as it is a transient, for control of parcelling return Objects.equals(mWifiInfo, that.mWifiInfo) && mSubId == that.mSubId; } @@ -105,17 +139,59 @@ public class VcnTransportInfo implements TransportInfo, Parcelable { return 0; } + @Override + @NonNull + public TransportInfo makeCopy(long redactions) { + return new VcnTransportInfo( + mWifiInfo == null ? null : mWifiInfo.makeCopy(redactions), mSubId, redactions); + } + + @Override + public long getApplicableRedactions() { + long redactions = REDACT_FOR_NETWORK_SETTINGS; + + // Add additional wifi redactions if necessary + if (mWifiInfo != null) { + redactions |= mWifiInfo.getApplicableRedactions(); + } + + return redactions; + } + + private boolean shouldParcelNetworkSettingsFields() { + return (mRedactions & NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS) == 0; + } + /** {@inheritDoc} */ @Override - public void writeToParcel(@NonNull Parcel dest, int flags) {} + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(shouldParcelNetworkSettingsFields() ? mSubId : INVALID_SUBSCRIPTION_ID); + dest.writeParcelable( + shouldParcelNetworkSettingsFields() ? (Parcelable) mWifiInfo : null, flags); + } + + @Override + public String toString() { + return "VcnTransportInfo { mWifiInfo = " + mWifiInfo + ", mSubId = " + mSubId + " }"; + } /** Implement the Parcelable interface */ public static final @NonNull Creator<VcnTransportInfo> CREATOR = new Creator<VcnTransportInfo>() { public VcnTransportInfo createFromParcel(Parcel in) { - // return null instead of a default VcnTransportInfo to avoid leaking - // information about this being a VCN Network (instead of macro cellular, etc) - return null; + final int subId = in.readInt(); + final WifiInfo wifiInfo = in.readParcelable(null); + + // If all fields are their null values, return null TransportInfo to avoid + // leaking information about this being a VCN Network (instead of macro + // cellular, etc) + if (wifiInfo == null && subId == INVALID_SUBSCRIPTION_ID) { + return null; + } + + // Prevent further forwarding by redacting everything in future parcels from + // this VcnTransportInfo + return new VcnTransportInfo(wifiInfo, subId, REDACT_ALL); } public VcnTransportInfo[] newArray(int size) { diff --git a/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java b/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java index 31561901be9e..582275d0547d 100644 --- a/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java +++ b/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java @@ -16,6 +16,8 @@ package android.net.vcn; +import static android.net.NetworkCapabilities.REDACT_ALL; +import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import static org.junit.Assert.assertEquals; @@ -37,6 +39,12 @@ public class VcnTransportInfoTest { private static final VcnTransportInfo WIFI_UNDERLYING_INFO = new VcnTransportInfo(WIFI_INFO); @Test + public void testRedactionDefaults() { + assertEquals(REDACT_ALL, CELL_UNDERLYING_INFO.getRedaction()); + assertEquals(REDACT_ALL, WIFI_UNDERLYING_INFO.getRedaction()); + } + + @Test public void testGetWifiInfo() { assertEquals(WIFI_INFO, WIFI_UNDERLYING_INFO.getWifiInfo()); @@ -51,6 +59,18 @@ public class VcnTransportInfoTest { } @Test + public void testMakeCopySetsRedactions() { + assertEquals( + REDACT_FOR_NETWORK_SETTINGS, + ((VcnTransportInfo) CELL_UNDERLYING_INFO.makeCopy(REDACT_FOR_NETWORK_SETTINGS)) + .getRedaction()); + assertEquals( + REDACT_FOR_NETWORK_SETTINGS, + ((VcnTransportInfo) WIFI_UNDERLYING_INFO.makeCopy(REDACT_FOR_NETWORK_SETTINGS)) + .getRedaction()); + } + + @Test public void testEquals() { assertEquals(CELL_UNDERLYING_INFO, CELL_UNDERLYING_INFO); assertEquals(WIFI_UNDERLYING_INFO, WIFI_UNDERLYING_INFO); @@ -64,8 +84,29 @@ public class VcnTransportInfoTest { } private void verifyParcelingIsNull(VcnTransportInfo vcnTransportInfo) { + // Verify redacted by default Parcel parcel = Parcel.obtain(); vcnTransportInfo.writeToParcel(parcel, 0 /* flags */); + parcel.setDataPosition(0); + assertNull(VcnTransportInfo.CREATOR.createFromParcel(parcel)); } + + @Test + public void testParcelUnparcelNotRedactedForSysUi() { + verifyParcelingForSysUi(CELL_UNDERLYING_INFO); + verifyParcelingForSysUi(WIFI_UNDERLYING_INFO); + } + + private void verifyParcelingForSysUi(VcnTransportInfo vcnTransportInfo) { + // Allow fully unredacted; SysUI will have all the relevant permissions. + final VcnTransportInfo unRedacted = (VcnTransportInfo) vcnTransportInfo.makeCopy(0); + final Parcel parcel = Parcel.obtain(); + unRedacted.writeToParcel(parcel, 0 /* flags */); + parcel.setDataPosition(0); + + final VcnTransportInfo unparceled = VcnTransportInfo.CREATOR.createFromParcel(parcel); + assertEquals(vcnTransportInfo, unparceled); + assertEquals(REDACT_ALL, unparceled.getRedaction()); + } } |