Merge "Add Network security watchlist service"

am: e672ab4c0a

Change-Id: I3e3d8dbc220879752826faa7570f04585c2f1107
This commit is contained in:
Hugo Benichi
2017-11-12 22:36:21 +00:00
committed by android-build-merger
6 changed files with 70 additions and 24 deletions

View File

@@ -30,11 +30,11 @@ interface IIpConnectivityMetrics {
int logEvent(in ConnectivityMetricsEvent event);
/**
* At most one callback can be registered (by DevicePolicyManager).
* Callback can be registered by DevicePolicyManager or NetworkWatchlistService only.
* @return status {@code true} if registering/unregistering of the callback was successful,
* {@code false} otherwise (might happen if IIpConnectivityMetrics is not available,
* if it happens make sure you call it when the service is up in the caller)
*/
boolean registerNetdEventCallback(in INetdEventCallback callback);
boolean unregisterNetdEventCallback();
boolean addNetdEventCallback(in int callerType, in INetdEventCallback callback);
boolean removeNetdEventCallback(in int callerType);
}

View File

@@ -19,6 +19,10 @@ package android.net;
/** {@hide} */
oneway interface INetdEventCallback {
// Possible addNetdEventCallback callers.
const int CALLBACK_CALLER_DEVICE_POLICY = 0;
const int CALLBACK_CALLER_NETWORK_WATCHLIST = 1;
/**
* Reports a single DNS lookup function call.
* This method must not block or perform long-running operations.

View File

@@ -23,8 +23,6 @@ import android.net.INetdEventCallback;
import android.net.metrics.ApfProgramEvent;
import android.net.metrics.IpConnectivityLog;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcelable;
import android.os.Process;
import android.provider.Settings;
import android.text.TextUtils;
@@ -322,22 +320,22 @@ final public class IpConnectivityMetrics extends SystemService {
}
@Override
public boolean registerNetdEventCallback(INetdEventCallback callback) {
public boolean addNetdEventCallback(int callerType, INetdEventCallback callback) {
enforceNetdEventListeningPermission();
if (mNetdListener == null) {
return false;
}
return mNetdListener.registerNetdEventCallback(callback);
return mNetdListener.addNetdEventCallback(callerType, callback);
}
@Override
public boolean unregisterNetdEventCallback() {
public boolean removeNetdEventCallback(int callerType) {
enforceNetdEventListeningPermission();
if (mNetdListener == null) {
// if the service is null, we aren't registered anyway
return true;
}
return mNetdListener.unregisterNetdEventCallback();
return mNetdListener.removeNetdEventCallback(callerType);
}
};

View File

@@ -98,21 +98,55 @@ public class NetdEventListenerService extends INetdEventListener.Stub {
@GuardedBy("this")
private final TokenBucket mConnectTb =
new TokenBucket(CONNECT_LATENCY_FILL_RATE, CONNECT_LATENCY_BURST_LIMIT);
// Callback should only be registered/unregistered when logging is being enabled/disabled in DPM
// by the device owner. It's DevicePolicyManager's responsibility to ensure that.
@GuardedBy("this")
private INetdEventCallback mNetdEventCallback;
public synchronized boolean registerNetdEventCallback(INetdEventCallback callback) {
mNetdEventCallback = callback;
/**
* There are only 2 possible callbacks.
*
* mNetdEventCallbackList[CALLBACK_CALLER_DEVICE_POLICY].
* Callback registered/unregistered when logging is being enabled/disabled in DPM
* by the device owner. It's DevicePolicyManager's responsibility to ensure that.
*
* mNetdEventCallbackList[CALLBACK_CALLER_NETWORK_WATCHLIST]
* Callback registered/unregistered by NetworkWatchlistService.
*/
@GuardedBy("this")
private static final int[] ALLOWED_CALLBACK_TYPES = {
INetdEventCallback.CALLBACK_CALLER_DEVICE_POLICY,
INetdEventCallback.CALLBACK_CALLER_NETWORK_WATCHLIST
};
@GuardedBy("this")
private INetdEventCallback[] mNetdEventCallbackList =
new INetdEventCallback[ALLOWED_CALLBACK_TYPES.length];
public synchronized boolean addNetdEventCallback(int callerType, INetdEventCallback callback) {
if (!isValidCallerType(callerType)) {
Log.e(TAG, "Invalid caller type: " + callerType);
return false;
}
mNetdEventCallbackList[callerType] = callback;
return true;
}
public synchronized boolean unregisterNetdEventCallback() {
mNetdEventCallback = null;
public synchronized boolean removeNetdEventCallback(int callerType) {
if (!isValidCallerType(callerType)) {
Log.e(TAG, "Invalid caller type: " + callerType);
return false;
}
mNetdEventCallbackList[callerType] = null;
return true;
}
private static boolean isValidCallerType(int callerType) {
for (int i = 0; i < ALLOWED_CALLBACK_TYPES.length; i++) {
if (callerType == ALLOWED_CALLBACK_TYPES[i]) {
return true;
}
}
return false;
}
public NetdEventListenerService(Context context) {
this(context.getSystemService(ConnectivityManager.class));
}
@@ -169,8 +203,10 @@ public class NetdEventListenerService extends INetdEventListener.Stub {
long timestamp = System.currentTimeMillis();
getMetricsForNetwork(timestamp, netId).addDnsResult(eventType, returnCode, latencyMs);
if (mNetdEventCallback != null) {
mNetdEventCallback.onDnsEvent(hostname, ipAddresses, ipAddressesCount, timestamp, uid);
for (INetdEventCallback callback : mNetdEventCallbackList) {
if (callback != null) {
callback.onDnsEvent(hostname, ipAddresses, ipAddressesCount, timestamp, uid);
}
}
}
@@ -184,8 +220,14 @@ public class NetdEventListenerService extends INetdEventListener.Stub {
long timestamp = System.currentTimeMillis();
getMetricsForNetwork(timestamp, netId).addConnectResult(error, latencyMs, ipAddr);
if (mNetdEventCallback != null) {
mNetdEventCallback.onConnectEvent(ipAddr, port, timestamp, uid);
for (INetdEventCallback callback : mNetdEventCallbackList) {
if (callback != null) {
// TODO(rickywai): Remove this checking to collect ip in watchlist.
if (callback ==
mNetdEventCallbackList[INetdEventCallback.CALLBACK_CALLER_DEVICE_POLICY]) {
callback.onConnectEvent(ipAddr, port, timestamp, uid);
}
}
}
}

View File

@@ -107,7 +107,8 @@ final class NetworkLogger {
return false;
}
try {
if (mIpConnectivityMetrics.registerNetdEventCallback(mNetdEventCallback)) {
if (mIpConnectivityMetrics.addNetdEventCallback(
INetdEventCallback.CALLBACK_CALLER_DEVICE_POLICY, mNetdEventCallback)) {
mHandlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_BACKGROUND,
/* allowIo */ false);
mHandlerThread.start();
@@ -138,7 +139,8 @@ final class NetworkLogger {
// logging is forcefully disabled even if unregistering fails
return true;
}
return mIpConnectivityMetrics.unregisterNetdEventCallback();
return mIpConnectivityMetrics.removeNetdEventCallback(
INetdEventCallback.CALLBACK_CALLER_DEVICE_POLICY);
} catch (RemoteException re) {
Slog.wtf(TAG, "Failed to make remote calls to unregister the callback", re);
return true;

View File

@@ -3150,7 +3150,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
// setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the
// feature is disabled because there are non-affiliated secondary users.
getServices().removeUser(DpmMockContext.CALLER_USER_HANDLE);
when(getServices().iipConnectivityMetrics.registerNetdEventCallback(anyObject()))
when(getServices().iipConnectivityMetrics.addNetdEventCallback(anyInt(), anyObject()))
.thenReturn(true);
// No logs were retrieved so far.