Merge changes from topic "xfrmi-support" am: f928c1e4b9

am: 719761f60c

Change-Id: I13a826f5ae3c4cb700be789b369848685da1bc41
This commit is contained in:
Benedict Wong
2018-11-25 19:26:26 -08:00
committed by android-build-merger
2 changed files with 102 additions and 33 deletions

View File

@@ -65,10 +65,13 @@ public final class IpSecConfig implements Parcelable {
// An interval, in seconds between the NattKeepalive packets // An interval, in seconds between the NattKeepalive packets
private int mNattKeepaliveInterval; private int mNattKeepaliveInterval;
// XFRM mark and mask // XFRM mark and mask; defaults to 0 (no mark/mask)
private int mMarkValue; private int mMarkValue;
private int mMarkMask; private int mMarkMask;
// XFRM interface id
private int mXfrmInterfaceId;
/** Set the mode for this IPsec transform */ /** Set the mode for this IPsec transform */
public void setMode(int mode) { public void setMode(int mode) {
mMode = mode; mMode = mode;
@@ -125,14 +128,30 @@ public final class IpSecConfig implements Parcelable {
mNattKeepaliveInterval = interval; mNattKeepaliveInterval = interval;
} }
/**
* Sets the mark value
*
* <p>Internal (System server) use only. Marks passed in by users will be overwritten or
* ignored.
*/
public void setMarkValue(int mark) { public void setMarkValue(int mark) {
mMarkValue = mark; mMarkValue = mark;
} }
/**
* Sets the mark mask
*
* <p>Internal (System server) use only. Marks passed in by users will be overwritten or
* ignored.
*/
public void setMarkMask(int mask) { public void setMarkMask(int mask) {
mMarkMask = mask; mMarkMask = mask;
} }
public void setXfrmInterfaceId(int xfrmInterfaceId) {
mXfrmInterfaceId = xfrmInterfaceId;
}
// Transport or Tunnel // Transport or Tunnel
public int getMode() { public int getMode() {
return mMode; return mMode;
@@ -190,6 +209,10 @@ public final class IpSecConfig implements Parcelable {
return mMarkMask; return mMarkMask;
} }
public int getXfrmInterfaceId() {
return mXfrmInterfaceId;
}
// Parcelable Methods // Parcelable Methods
@Override @Override
@@ -213,6 +236,7 @@ public final class IpSecConfig implements Parcelable {
out.writeInt(mNattKeepaliveInterval); out.writeInt(mNattKeepaliveInterval);
out.writeInt(mMarkValue); out.writeInt(mMarkValue);
out.writeInt(mMarkMask); out.writeInt(mMarkMask);
out.writeInt(mXfrmInterfaceId);
} }
@VisibleForTesting @VisibleForTesting
@@ -235,6 +259,7 @@ public final class IpSecConfig implements Parcelable {
mNattKeepaliveInterval = c.mNattKeepaliveInterval; mNattKeepaliveInterval = c.mNattKeepaliveInterval;
mMarkValue = c.mMarkValue; mMarkValue = c.mMarkValue;
mMarkMask = c.mMarkMask; mMarkMask = c.mMarkMask;
mXfrmInterfaceId = c.mXfrmInterfaceId;
} }
private IpSecConfig(Parcel in) { private IpSecConfig(Parcel in) {
@@ -255,6 +280,7 @@ public final class IpSecConfig implements Parcelable {
mNattKeepaliveInterval = in.readInt(); mNattKeepaliveInterval = in.readInt();
mMarkValue = in.readInt(); mMarkValue = in.readInt();
mMarkMask = in.readInt(); mMarkMask = in.readInt();
mXfrmInterfaceId = in.readInt();
} }
@Override @Override
@@ -289,6 +315,8 @@ public final class IpSecConfig implements Parcelable {
.append(mMarkValue) .append(mMarkValue)
.append(", mMarkMask=") .append(", mMarkMask=")
.append(mMarkMask) .append(mMarkMask)
.append(", mXfrmInterfaceId=")
.append(mXfrmInterfaceId)
.append("}"); .append("}");
return strBuilder.toString(); return strBuilder.toString();
@@ -320,10 +348,10 @@ public final class IpSecConfig implements Parcelable {
&& lhs.mNattKeepaliveInterval == rhs.mNattKeepaliveInterval && lhs.mNattKeepaliveInterval == rhs.mNattKeepaliveInterval
&& lhs.mSpiResourceId == rhs.mSpiResourceId && lhs.mSpiResourceId == rhs.mSpiResourceId
&& IpSecAlgorithm.equals(lhs.mEncryption, rhs.mEncryption) && IpSecAlgorithm.equals(lhs.mEncryption, rhs.mEncryption)
&& IpSecAlgorithm.equals( && IpSecAlgorithm.equals(lhs.mAuthenticatedEncryption, rhs.mAuthenticatedEncryption)
lhs.mAuthenticatedEncryption, rhs.mAuthenticatedEncryption)
&& IpSecAlgorithm.equals(lhs.mAuthentication, rhs.mAuthentication) && IpSecAlgorithm.equals(lhs.mAuthentication, rhs.mAuthentication)
&& lhs.mMarkValue == rhs.mMarkValue && lhs.mMarkValue == rhs.mMarkValue
&& lhs.mMarkMask == rhs.mMarkMask); && lhs.mMarkMask == rhs.mMarkMask
&& lhs.mXfrmInterfaceId == rhs.mXfrmInterfaceId);
} }
} }

View File

@@ -24,6 +24,7 @@ import static android.system.OsConstants.AF_UNSPEC;
import static android.system.OsConstants.EINVAL; import static android.system.OsConstants.EINVAL;
import static android.system.OsConstants.IPPROTO_UDP; import static android.system.OsConstants.IPPROTO_UDP;
import static android.system.OsConstants.SOCK_DGRAM; import static android.system.OsConstants.SOCK_DGRAM;
import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.internal.util.Preconditions.checkNotNull;
import android.annotation.NonNull; import android.annotation.NonNull;
@@ -62,6 +63,8 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions; import com.android.internal.util.Preconditions;
import libcore.io.IoUtils;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
@@ -73,8 +76,6 @@ import java.net.UnknownHostException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import libcore.io.IoUtils;
/** /**
* A service to manage multiple clients that want to access the IpSec API. The service is * A service to manage multiple clients that want to access the IpSec API. The service is
* responsible for maintaining a list of clients and managing the resources (and related quotas) * responsible for maintaining a list of clients and managing the resources (and related quotas)
@@ -621,7 +622,8 @@ public class IpSecService extends IIpSecService.Stub {
mConfig.getDestinationAddress(), mConfig.getDestinationAddress(),
spi, spi,
mConfig.getMarkValue(), mConfig.getMarkValue(),
mConfig.getMarkMask()); mConfig.getMarkMask(),
mConfig.getXfrmInterfaceId());
} catch (RemoteException | ServiceSpecificException e) { } catch (RemoteException | ServiceSpecificException e) {
Log.e(TAG, "Failed to delete SA with ID: " + mResourceId, e); Log.e(TAG, "Failed to delete SA with ID: " + mResourceId, e);
} }
@@ -683,7 +685,8 @@ public class IpSecService extends IIpSecService.Stub {
mSrvConfig mSrvConfig
.getNetdInstance() .getNetdInstance()
.ipSecDeleteSecurityAssociation( .ipSecDeleteSecurityAssociation(
uid, mSourceAddress, mDestinationAddress, mSpi, 0, 0); uid, mSourceAddress, mDestinationAddress, mSpi, 0 /* mark */,
0 /* mask */, 0 /* if_id */);
} }
} catch (ServiceSpecificException | RemoteException e) { } catch (ServiceSpecificException | RemoteException e) {
Log.e(TAG, "Failed to delete SPI reservation with ID: " + mResourceId, e); Log.e(TAG, "Failed to delete SPI reservation with ID: " + mResourceId, e);
@@ -795,6 +798,8 @@ public class IpSecService extends IIpSecService.Stub {
private final int mIkey; private final int mIkey;
private final int mOkey; private final int mOkey;
private final int mIfId;
TunnelInterfaceRecord( TunnelInterfaceRecord(
int resourceId, int resourceId,
String interfaceName, String interfaceName,
@@ -802,7 +807,8 @@ public class IpSecService extends IIpSecService.Stub {
String localAddr, String localAddr,
String remoteAddr, String remoteAddr,
int ikey, int ikey,
int okey) { int okey,
int intfId) {
super(resourceId); super(resourceId);
mInterfaceName = interfaceName; mInterfaceName = interfaceName;
@@ -811,6 +817,7 @@ public class IpSecService extends IIpSecService.Stub {
mRemoteAddress = remoteAddr; mRemoteAddress = remoteAddr;
mIkey = ikey; mIkey = ikey;
mOkey = okey; mOkey = okey;
mIfId = intfId;
} }
/** always guarded by IpSecService#this */ /** always guarded by IpSecService#this */
@@ -821,7 +828,7 @@ public class IpSecService extends IIpSecService.Stub {
// Delete global policies // Delete global policies
try { try {
final INetd netd = mSrvConfig.getNetdInstance(); final INetd netd = mSrvConfig.getNetdInstance();
netd.removeVirtualTunnelInterface(mInterfaceName); netd.ipSecRemoveTunnelInterface(mInterfaceName);
for (int selAddrFamily : ADDRESS_FAMILIES) { for (int selAddrFamily : ADDRESS_FAMILIES) {
netd.ipSecDeleteSecurityPolicy( netd.ipSecDeleteSecurityPolicy(
@@ -829,13 +836,15 @@ public class IpSecService extends IIpSecService.Stub {
selAddrFamily, selAddrFamily,
IpSecManager.DIRECTION_OUT, IpSecManager.DIRECTION_OUT,
mOkey, mOkey,
0xffffffff); 0xffffffff,
mIfId);
netd.ipSecDeleteSecurityPolicy( netd.ipSecDeleteSecurityPolicy(
uid, uid,
selAddrFamily, selAddrFamily,
IpSecManager.DIRECTION_IN, IpSecManager.DIRECTION_IN,
mIkey, mIkey,
0xffffffff); 0xffffffff,
mIfId);
} }
} catch (ServiceSpecificException | RemoteException e) { } catch (ServiceSpecificException | RemoteException e) {
Log.e( Log.e(
@@ -877,6 +886,10 @@ public class IpSecService extends IIpSecService.Stub {
return mOkey; return mOkey;
} }
public int getIfId() {
return mIfId;
}
@Override @Override
protected ResourceTracker getResourceTracker() { protected ResourceTracker getResourceTracker() {
return getUserRecord().mTunnelQuotaTracker; return getUserRecord().mTunnelQuotaTracker;
@@ -1286,7 +1299,7 @@ public class IpSecService extends IIpSecService.Stub {
// Add inbound/outbound global policies // Add inbound/outbound global policies
// (use reqid = 0) // (use reqid = 0)
final INetd netd = mSrvConfig.getNetdInstance(); final INetd netd = mSrvConfig.getNetdInstance();
netd.addVirtualTunnelInterface(intfName, localAddr, remoteAddr, ikey, okey); netd.ipSecAddTunnelInterface(intfName, localAddr, remoteAddr, ikey, okey, resourceId);
for (int selAddrFamily : ADDRESS_FAMILIES) { for (int selAddrFamily : ADDRESS_FAMILIES) {
// Always send down correct local/remote addresses for template. // Always send down correct local/remote addresses for template.
@@ -1298,7 +1311,8 @@ public class IpSecService extends IIpSecService.Stub {
remoteAddr, remoteAddr,
0, 0,
okey, okey,
0xffffffff); 0xffffffff,
resourceId);
netd.ipSecAddSecurityPolicy( netd.ipSecAddSecurityPolicy(
callerUid, callerUid,
selAddrFamily, selAddrFamily,
@@ -1307,7 +1321,8 @@ public class IpSecService extends IIpSecService.Stub {
localAddr, localAddr,
0, 0,
ikey, ikey,
0xffffffff); 0xffffffff,
resourceId);
} }
userRecord.mTunnelInterfaceRecords.put( userRecord.mTunnelInterfaceRecords.put(
@@ -1320,7 +1335,8 @@ public class IpSecService extends IIpSecService.Stub {
localAddr, localAddr,
remoteAddr, remoteAddr,
ikey, ikey,
okey), okey,
resourceId),
binder)); binder));
return new IpSecTunnelInterfaceResponse(IpSecManager.Status.OK, resourceId, intfName); return new IpSecTunnelInterfaceResponse(IpSecManager.Status.OK, resourceId, intfName);
} catch (RemoteException e) { } catch (RemoteException e) {
@@ -1523,6 +1539,9 @@ public class IpSecService extends IIpSecService.Stub {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Invalid IpSecTransform.mode: " + config.getMode()); "Invalid IpSecTransform.mode: " + config.getMode());
} }
config.setMarkValue(0);
config.setMarkMask(0);
} }
private static final String TUNNEL_OP = AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS; private static final String TUNNEL_OP = AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS;
@@ -1584,7 +1603,8 @@ public class IpSecService extends IIpSecService.Stub {
(authCrypt != null) ? authCrypt.getTruncationLengthBits() : 0, (authCrypt != null) ? authCrypt.getTruncationLengthBits() : 0,
encapType, encapType,
encapLocalPort, encapLocalPort,
encapRemotePort); encapRemotePort,
c.getXfrmInterfaceId());
} }
/** /**
@@ -1740,27 +1760,48 @@ public class IpSecService extends IIpSecService.Stub {
: tunnelInterfaceInfo.getIkey(); : tunnelInterfaceInfo.getIkey();
try { try {
c.setMarkValue(mark); // Default to using the invalid SPI of 0 for inbound SAs. This allows policies to skip
c.setMarkMask(0xffffffff); // SPI matching as part of the template resolution.
int spi = IpSecManager.INVALID_SECURITY_PARAMETER_INDEX;
c.setXfrmInterfaceId(tunnelInterfaceInfo.getIfId());
// TODO: enable this when UPDSA supports updating marks. Adding kernel support upstream
// (and backporting) would allow us to narrow the mark space, and ensure that the SA
// and SPs have matching marks (as VTI are meant to be built).
// Currently update does nothing with marks. Leave empty (defaulting to 0) to ensure the
// config matches the actual allocated resources in the kernel.
// All SAs will have zero marks (from creation time), and any policy that matches the
// same src/dst could match these SAs. Non-IpSecService governed processes that
// establish floating policies with the same src/dst may result in undefined
// behavior. This is generally limited to vendor code due to the permissions
// (CAP_NET_ADMIN) required.
//
// c.setMarkValue(mark);
// c.setMarkMask(0xffffffff);
if (direction == IpSecManager.DIRECTION_OUT) { if (direction == IpSecManager.DIRECTION_OUT) {
// Set output mark via underlying network (output only) // Set output mark via underlying network (output only)
c.setNetwork(tunnelInterfaceInfo.getUnderlyingNetwork()); c.setNetwork(tunnelInterfaceInfo.getUnderlyingNetwork());
// If outbound, also add SPI to the policy. // Set outbound SPI only. We want inbound to use any valid SA (old, new) on rekeys,
for (int selAddrFamily : ADDRESS_FAMILIES) { // but want to guarantee outbound packets are sent over the new SA.
mSrvConfig spi = transformInfo.getSpiRecord().getSpi();
.getNetdInstance() }
.ipSecUpdateSecurityPolicy(
callingUid, // Always update the policy with the relevant XFRM_IF_ID
selAddrFamily, for (int selAddrFamily : ADDRESS_FAMILIES) {
direction, mSrvConfig
tunnelInterfaceInfo.getLocalAddress(), .getNetdInstance()
tunnelInterfaceInfo.getRemoteAddress(), .ipSecUpdateSecurityPolicy(
transformInfo.getSpiRecord().getSpi(), callingUid,
mark, selAddrFamily,
0xffffffff); direction,
} transformInfo.getConfig().getSourceAddress(),
transformInfo.getConfig().getDestinationAddress(),
spi, // If outbound, also add SPI to the policy.
mark, // Must always set policy mark; ikey/okey for VTIs
0xffffffff,
c.getXfrmInterfaceId());
} }
// Update SA with tunnel mark (ikey or okey based on direction) // Update SA with tunnel mark (ikey or okey based on direction)