Loading services/core/java/com/android/server/security/intrusiondetection/DataAggregator.java +13 −1 Original line number Diff line number Diff line Loading @@ -36,6 +36,9 @@ public class DataAggregator { private static final int MSG_DISABLE = 2; private static final int STORED_EVENTS_SIZE_LIMIT = 1024; private static final IntrusionDetectionAdminReceiver ADMIN_RECEIVER = new IntrusionDetectionAdminReceiver(); private final IntrusionDetectionService mIntrusionDetectionService; private final ArrayList<DataSource> mDataSources; Loading @@ -60,10 +63,19 @@ public class DataAggregator { * Initialize DataSources * @return Whether the initialization succeeds. */ // TODO: Add the corresponding data sources public boolean initialize() { SecurityLogSource securityLogSource = new SecurityLogSource(mContext, this); mDataSources.add(securityLogSource); NetworkLogSource networkLogSource = new NetworkLogSource(mContext, this); ADMIN_RECEIVER.setNetworkLogEventCallback(networkLogSource); mDataSources.add(networkLogSource); for (DataSource ds : mDataSources) { if (!ds.initialize()) { return false; } } return true; } Loading services/core/java/com/android/server/security/intrusiondetection/DataSource.java +5 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,11 @@ package com.android.server.security.intrusiondetection; public interface DataSource { /** * Initialize the data source. */ boolean initialize(); /** * Enable the data collection. */ Loading services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionAdminReceiver.java 0 → 100644 +42 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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 com.android.server.security.intrusiondetection; import android.app.admin.DeviceAdminReceiver; import android.content.Context; import android.content.Intent; import android.util.Slog; public class IntrusionDetectionAdminReceiver extends DeviceAdminReceiver { private static final String TAG = "IntrusionDetectionAdminReceiver"; private static NetworkLogSource sNetworkLogSource; @Override public void onNetworkLogsAvailable( Context context, Intent intent, long batchToken, int networkLogsCount) { if (sNetworkLogSource != null) { sNetworkLogSource.onNetworkLogsAvailable(batchToken); } else { Slog.w(TAG, "Network log receiver is not initialized"); } } public void setNetworkLogEventCallback(NetworkLogSource networkLogSource) { sNetworkLogSource = networkLogSource; } } services/core/java/com/android/server/security/intrusiondetection/NetworkLogSource.java 0 → 100644 +134 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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 com.android.server.security.intrusiondetection; import android.app.admin.ConnectEvent; import android.app.admin.DevicePolicyManager; import android.app.admin.DnsEvent; import android.app.admin.NetworkEvent; import android.content.ComponentName; import android.content.Context; import android.security.intrusiondetection.IntrusionDetectionEvent; import android.util.Slog; import java.util.List; import java.util.stream.Collectors; public class NetworkLogSource implements DataSource { private static final String TAG = "IntrusionDetectionEvent NetworkLogSource"; private DevicePolicyManager mDpm; private ComponentName mAdmin; private DataAggregator mDataAggregator; public NetworkLogSource(Context context, DataAggregator dataAggregator) { mDataAggregator = dataAggregator; mDpm = context.getSystemService(DevicePolicyManager.class); mAdmin = new ComponentName(context, IntrusionDetectionAdminReceiver.class); } @Override public boolean initialize() { try { if (!mDpm.isAdminActive(mAdmin)) { Slog.e(TAG, "Admin " + mAdmin.flattenToString() + "is not active admin"); return false; } } catch (SecurityException e) { Slog.e(TAG, "Security exception in initialize: ", e); return false; } return true; } @Override public void enable() { enableNetworkLog(); } @Override public void disable() { disableNetworkLog(); } private void enableNetworkLog() { if (!isNetworkLogEnabled()) { mDpm.setNetworkLoggingEnabled(mAdmin, true); } } private void disableNetworkLog() { if (isNetworkLogEnabled()) { mDpm.setNetworkLoggingEnabled(mAdmin, false); } } private boolean isNetworkLogEnabled() { return mDpm.isNetworkLoggingEnabled(mAdmin); } /** * Retrieve network logs when onNetworkLogsAvailable callback is received. * * @param batchToken The token representing the current batch of network logs. */ public void onNetworkLogsAvailable(long batchToken) { List<NetworkEvent> events; try { events = mDpm.retrieveNetworkLogs(mAdmin, batchToken); } catch (SecurityException e) { Slog.e( TAG, "Admin " + mAdmin.flattenToString() + "does not have permission to retrieve network logs", e); return; } if (events == null) { if (!isNetworkLogEnabled()) { Slog.w(TAG, "Network logging is disabled"); } else { Slog.e(TAG, "Invalid batch token: " + batchToken); } return; } List<IntrusionDetectionEvent> intrusionDetectionEvents = events.stream() .filter(event -> event != null) .map(event -> toIntrusionDetectionEvent(event)) .collect(Collectors.toList()); mDataAggregator.addBatchData(intrusionDetectionEvents); } private IntrusionDetectionEvent toIntrusionDetectionEvent(NetworkEvent event) { if (event instanceof DnsEvent) { DnsEvent dnsEvent = (DnsEvent) event; return new IntrusionDetectionEvent(dnsEvent); } else if (event instanceof ConnectEvent) { ConnectEvent connectEvent = (ConnectEvent) event; return new IntrusionDetectionEvent(connectEvent); } throw new IllegalArgumentException( "Invalid event type with ID: " + event.getId() + "from package: " + event.getPackageName()); } } services/core/java/com/android/server/security/intrusiondetection/SecurityLogSource.java +21 −7 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.app.admin.DevicePolicyManager; import android.app.admin.SecurityLog.SecurityEvent; import android.content.Context; import android.security.intrusiondetection.IntrusionDetectionEvent; import android.util.Slog; import java.util.List; import java.util.concurrent.Executor; Loading @@ -33,7 +34,7 @@ public class SecurityLogSource implements DataSource { private static final String TAG = "IntrusionDetection SecurityLogSource"; private SecurityEventCallback mEventCallback = new SecurityEventCallback(); private SecurityEventCallback mEventCallback; private DevicePolicyManager mDpm; private Executor mExecutor; private DataAggregator mDataAggregator; Loading @@ -42,9 +43,26 @@ public class SecurityLogSource implements DataSource { mDataAggregator = dataAggregator; mDpm = context.getSystemService(DevicePolicyManager.class); mExecutor = Executors.newSingleThreadExecutor(); } @Override public boolean initialize() { // Confirm caller is system and the device is managed. Otherwise logs will // be redacted. try { if (!mDpm.isDeviceManaged()) { Slog.e(TAG, "Caller does not have device owner permissions"); return false; } } catch (SecurityException e) { Slog.e(TAG, "Security exception in initialize: ", e); return false; } mEventCallback = new SecurityEventCallback(); return true; } @Override @RequiresPermission(permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING) public void enable() { Loading Loading @@ -72,12 +90,8 @@ public class SecurityLogSource implements DataSource { } } /** * Check if security audit logging is enabled for the caller. * * @return Whether security audit logging is enabled. */ public boolean isAuditLogEnabled() { @RequiresPermission(permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING) private boolean isAuditLogEnabled() { return mDpm.isAuditLogEnabled(); } Loading Loading
services/core/java/com/android/server/security/intrusiondetection/DataAggregator.java +13 −1 Original line number Diff line number Diff line Loading @@ -36,6 +36,9 @@ public class DataAggregator { private static final int MSG_DISABLE = 2; private static final int STORED_EVENTS_SIZE_LIMIT = 1024; private static final IntrusionDetectionAdminReceiver ADMIN_RECEIVER = new IntrusionDetectionAdminReceiver(); private final IntrusionDetectionService mIntrusionDetectionService; private final ArrayList<DataSource> mDataSources; Loading @@ -60,10 +63,19 @@ public class DataAggregator { * Initialize DataSources * @return Whether the initialization succeeds. */ // TODO: Add the corresponding data sources public boolean initialize() { SecurityLogSource securityLogSource = new SecurityLogSource(mContext, this); mDataSources.add(securityLogSource); NetworkLogSource networkLogSource = new NetworkLogSource(mContext, this); ADMIN_RECEIVER.setNetworkLogEventCallback(networkLogSource); mDataSources.add(networkLogSource); for (DataSource ds : mDataSources) { if (!ds.initialize()) { return false; } } return true; } Loading
services/core/java/com/android/server/security/intrusiondetection/DataSource.java +5 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,11 @@ package com.android.server.security.intrusiondetection; public interface DataSource { /** * Initialize the data source. */ boolean initialize(); /** * Enable the data collection. */ Loading
services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionAdminReceiver.java 0 → 100644 +42 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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 com.android.server.security.intrusiondetection; import android.app.admin.DeviceAdminReceiver; import android.content.Context; import android.content.Intent; import android.util.Slog; public class IntrusionDetectionAdminReceiver extends DeviceAdminReceiver { private static final String TAG = "IntrusionDetectionAdminReceiver"; private static NetworkLogSource sNetworkLogSource; @Override public void onNetworkLogsAvailable( Context context, Intent intent, long batchToken, int networkLogsCount) { if (sNetworkLogSource != null) { sNetworkLogSource.onNetworkLogsAvailable(batchToken); } else { Slog.w(TAG, "Network log receiver is not initialized"); } } public void setNetworkLogEventCallback(NetworkLogSource networkLogSource) { sNetworkLogSource = networkLogSource; } }
services/core/java/com/android/server/security/intrusiondetection/NetworkLogSource.java 0 → 100644 +134 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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 com.android.server.security.intrusiondetection; import android.app.admin.ConnectEvent; import android.app.admin.DevicePolicyManager; import android.app.admin.DnsEvent; import android.app.admin.NetworkEvent; import android.content.ComponentName; import android.content.Context; import android.security.intrusiondetection.IntrusionDetectionEvent; import android.util.Slog; import java.util.List; import java.util.stream.Collectors; public class NetworkLogSource implements DataSource { private static final String TAG = "IntrusionDetectionEvent NetworkLogSource"; private DevicePolicyManager mDpm; private ComponentName mAdmin; private DataAggregator mDataAggregator; public NetworkLogSource(Context context, DataAggregator dataAggregator) { mDataAggregator = dataAggregator; mDpm = context.getSystemService(DevicePolicyManager.class); mAdmin = new ComponentName(context, IntrusionDetectionAdminReceiver.class); } @Override public boolean initialize() { try { if (!mDpm.isAdminActive(mAdmin)) { Slog.e(TAG, "Admin " + mAdmin.flattenToString() + "is not active admin"); return false; } } catch (SecurityException e) { Slog.e(TAG, "Security exception in initialize: ", e); return false; } return true; } @Override public void enable() { enableNetworkLog(); } @Override public void disable() { disableNetworkLog(); } private void enableNetworkLog() { if (!isNetworkLogEnabled()) { mDpm.setNetworkLoggingEnabled(mAdmin, true); } } private void disableNetworkLog() { if (isNetworkLogEnabled()) { mDpm.setNetworkLoggingEnabled(mAdmin, false); } } private boolean isNetworkLogEnabled() { return mDpm.isNetworkLoggingEnabled(mAdmin); } /** * Retrieve network logs when onNetworkLogsAvailable callback is received. * * @param batchToken The token representing the current batch of network logs. */ public void onNetworkLogsAvailable(long batchToken) { List<NetworkEvent> events; try { events = mDpm.retrieveNetworkLogs(mAdmin, batchToken); } catch (SecurityException e) { Slog.e( TAG, "Admin " + mAdmin.flattenToString() + "does not have permission to retrieve network logs", e); return; } if (events == null) { if (!isNetworkLogEnabled()) { Slog.w(TAG, "Network logging is disabled"); } else { Slog.e(TAG, "Invalid batch token: " + batchToken); } return; } List<IntrusionDetectionEvent> intrusionDetectionEvents = events.stream() .filter(event -> event != null) .map(event -> toIntrusionDetectionEvent(event)) .collect(Collectors.toList()); mDataAggregator.addBatchData(intrusionDetectionEvents); } private IntrusionDetectionEvent toIntrusionDetectionEvent(NetworkEvent event) { if (event instanceof DnsEvent) { DnsEvent dnsEvent = (DnsEvent) event; return new IntrusionDetectionEvent(dnsEvent); } else if (event instanceof ConnectEvent) { ConnectEvent connectEvent = (ConnectEvent) event; return new IntrusionDetectionEvent(connectEvent); } throw new IllegalArgumentException( "Invalid event type with ID: " + event.getId() + "from package: " + event.getPackageName()); } }
services/core/java/com/android/server/security/intrusiondetection/SecurityLogSource.java +21 −7 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.app.admin.DevicePolicyManager; import android.app.admin.SecurityLog.SecurityEvent; import android.content.Context; import android.security.intrusiondetection.IntrusionDetectionEvent; import android.util.Slog; import java.util.List; import java.util.concurrent.Executor; Loading @@ -33,7 +34,7 @@ public class SecurityLogSource implements DataSource { private static final String TAG = "IntrusionDetection SecurityLogSource"; private SecurityEventCallback mEventCallback = new SecurityEventCallback(); private SecurityEventCallback mEventCallback; private DevicePolicyManager mDpm; private Executor mExecutor; private DataAggregator mDataAggregator; Loading @@ -42,9 +43,26 @@ public class SecurityLogSource implements DataSource { mDataAggregator = dataAggregator; mDpm = context.getSystemService(DevicePolicyManager.class); mExecutor = Executors.newSingleThreadExecutor(); } @Override public boolean initialize() { // Confirm caller is system and the device is managed. Otherwise logs will // be redacted. try { if (!mDpm.isDeviceManaged()) { Slog.e(TAG, "Caller does not have device owner permissions"); return false; } } catch (SecurityException e) { Slog.e(TAG, "Security exception in initialize: ", e); return false; } mEventCallback = new SecurityEventCallback(); return true; } @Override @RequiresPermission(permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING) public void enable() { Loading Loading @@ -72,12 +90,8 @@ public class SecurityLogSource implements DataSource { } } /** * Check if security audit logging is enabled for the caller. * * @return Whether security audit logging is enabled. */ public boolean isAuditLogEnabled() { @RequiresPermission(permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING) private boolean isAuditLogEnabled() { return mDpm.isAuditLogEnabled(); } Loading