• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.app.admin;
18 
19 import android.Manifest;
20 import android.annotation.IntDef;
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.annotation.RequiresPermission;
24 import android.annotation.SystemApi;
25 import android.annotation.TestApi;
26 import android.compat.annotation.UnsupportedAppUsage;
27 import android.content.ComponentName;
28 import android.os.Build;
29 import android.os.Parcel;
30 import android.os.Parcelable;
31 import android.os.SystemProperties;
32 import android.os.UserHandle;
33 import android.util.EventLog.Event;
34 
35 import java.io.IOException;
36 import java.lang.annotation.Retention;
37 import java.lang.annotation.RetentionPolicy;
38 import java.util.ArrayList;
39 import java.util.Collection;
40 import java.util.Objects;
41 
42 /**
43  * Definitions for working with security logs.
44  *
45  * <p>Device owner apps can control the logging with
46  * {@link DevicePolicyManager#setSecurityLoggingEnabled}. When security logs are enabled, device
47  * owner apps receive periodic callbacks from {@link DeviceAdminReceiver#onSecurityLogsAvailable},
48  * at which time new batch of logs can be collected via
49  * {@link DevicePolicyManager#retrieveSecurityLogs}. {@link SecurityEvent} describes the type and
50  * format of security logs being collected.
51  */
52 public class SecurityLog {
53 
54     private static final String PROPERTY_LOGGING_ENABLED = "persist.logd.security";
55 
56     /** @hide */
57     @Retention(RetentionPolicy.SOURCE)
58     @IntDef(prefix = { "TAG_" }, value = {
59             TAG_ADB_SHELL_INTERACTIVE,
60             TAG_ADB_SHELL_CMD,
61             TAG_SYNC_RECV_FILE,
62             TAG_SYNC_SEND_FILE,
63             TAG_APP_PROCESS_START,
64             TAG_KEYGUARD_DISMISSED,
65             TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT,
66             TAG_KEYGUARD_SECURED,
67             TAG_OS_STARTUP,
68             TAG_OS_SHUTDOWN,
69             TAG_LOGGING_STARTED,
70             TAG_LOGGING_STOPPED,
71             TAG_MEDIA_MOUNT,
72             TAG_MEDIA_UNMOUNT,
73             TAG_LOG_BUFFER_SIZE_CRITICAL,
74             TAG_PASSWORD_EXPIRATION_SET,
75             TAG_PASSWORD_COMPLEXITY_SET,
76             TAG_PASSWORD_HISTORY_LENGTH_SET,
77             TAG_MAX_SCREEN_LOCK_TIMEOUT_SET,
78             TAG_MAX_PASSWORD_ATTEMPTS_SET,
79             TAG_KEYGUARD_DISABLED_FEATURES_SET,
80             TAG_REMOTE_LOCK,
81             TAG_USER_RESTRICTION_ADDED,
82             TAG_USER_RESTRICTION_REMOVED,
83             TAG_WIPE_FAILURE,
84             TAG_KEY_GENERATED,
85             TAG_KEY_IMPORT,
86             TAG_KEY_DESTRUCTION,
87             TAG_CERT_AUTHORITY_INSTALLED,
88             TAG_CERT_AUTHORITY_REMOVED,
89             TAG_CRYPTO_SELF_TEST_COMPLETED,
90             TAG_KEY_INTEGRITY_VIOLATION,
91             TAG_CERT_VALIDATION_FAILURE,
92             TAG_CAMERA_POLICY_SET,
93             TAG_PASSWORD_COMPLEXITY_REQUIRED,
94             TAG_PASSWORD_CHANGED,
95             TAG_WIFI_CONNECTION,
96             TAG_WIFI_DISCONNECTION,
97             TAG_BLUETOOTH_CONNECTION,
98             TAG_BLUETOOTH_DISCONNECTION,
99     })
100     public @interface SecurityLogTag {}
101 
102     /** @hide */
103     @Retention(RetentionPolicy.SOURCE)
104     @IntDef(prefix = { "LEVEL_" }, value = {
105             LEVEL_INFO,
106             LEVEL_WARNING,
107             LEVEL_ERROR
108     })
109     public @interface SecurityLogLevel {}
110 
111     /**
112      * Indicates that an ADB interactive shell was opened via "adb shell".
113      * There is no extra payload in the log event.
114      */
115     public static final int TAG_ADB_SHELL_INTERACTIVE =
116             SecurityLogTags.SECURITY_ADB_SHELL_INTERACTIVE;
117 
118     /**
119      * Indicates that a shell command was issued over ADB via {@code adb shell <command>}
120      * The log entry contains a {@code String} payload containing the shell command, accessible
121      * via {@link SecurityEvent#getData()}. If security logging is enabled on organization-owned
122      * managed profile devices, the shell command will be redacted to an empty string.
123      */
124     public static final int TAG_ADB_SHELL_CMD = SecurityLogTags.SECURITY_ADB_SHELL_COMMAND;
125 
126     /**
127      * Indicates that a file was pulled from the device via the adb daemon, for example via
128      * {@code adb pull}. The log entry contains a {@code String} payload containing the path of the
129      * pulled file on the device, accessible via {@link SecurityEvent#getData()}.
130      */
131     public static final int TAG_SYNC_RECV_FILE = SecurityLogTags.SECURITY_ADB_SYNC_RECV;
132 
133     /**
134      * Indicates that a file was pushed to the device via the adb daemon, for example via
135      * {@code adb push}. The log entry contains a {@code String} payload containing the destination
136      * path of the pushed file, accessible via {@link SecurityEvent#getData()}.
137      */
138     public static final int TAG_SYNC_SEND_FILE = SecurityLogTags.SECURITY_ADB_SYNC_SEND;
139 
140     /**
141      * Indicates that an app process was started. The log entry contains the following
142      * information about the process encapsulated in an {@link Object} array, accessible via
143      * {@link SecurityEvent#getData()}:
144      * <li> [0] process name ({@code String})
145      * <li> [1] exact start time in milliseconds according to {@code System.currentTimeMillis()}
146      *      ({@code Long})
147      * <li> [2] app uid ({@code Integer})
148      * <li> [3] app pid ({@code Integer})
149      * <li> [4] seinfo tag ({@code String})
150      * <li> [5] SHA-256 hash of the base APK in hexadecimal ({@code String})
151      * If security logging is enabled on organization-owned managed profile devices, only events
152      * happening inside the managed profile will be visible.
153      */
154     public static final int TAG_APP_PROCESS_START = SecurityLogTags.SECURITY_APP_PROCESS_START;
155 
156     /**
157      * Indicates that keyguard has been dismissed. This event is only logged if the device
158      * has a secure keyguard. It is logged regardless of how keyguard is dismissed, including
159      * via PIN/pattern/password, biometrics or via a trust agent.
160      * There is no extra payload in the log event.
161      * @see #TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT
162      */
163     public static final int TAG_KEYGUARD_DISMISSED = SecurityLogTags.SECURITY_KEYGUARD_DISMISSED;
164 
165     /**
166      * Indicates that there has been an authentication attempt to dismiss the keyguard. The log
167      * entry contains the following information about the attempt encapsulated in an {@link Object}
168      * array, accessible via {@link SecurityEvent#getData()}:
169      * <li> [0] attempt result ({@code Integer}, 1 for successful, 0 for unsuccessful)
170      * <li> [1] strength of authentication method ({@code Integer}, 1 if strong authentication
171      *      method was used, 0 otherwise)
172      */
173     public static final int TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT =
174             SecurityLogTags.SECURITY_KEYGUARD_DISMISS_AUTH_ATTEMPT;
175 
176     /**
177      * Indicates that the device has been locked, either by the user or by a timeout. There is no
178      * extra payload in the log event.
179      */
180     public static final int TAG_KEYGUARD_SECURED = SecurityLogTags.SECURITY_KEYGUARD_SECURED;
181 
182     /**
183      * Indicates that the Android OS has started. The log entry contains the following information
184      * about the startup time software integrity check encapsulated in an {@link Object} array,
185      * accessible via {@link SecurityEvent#getData()}:
186      * <li> [0] Verified Boot state ({@code String})
187      * <li> [1] dm-verity mode ({@code String}).
188      * <p>Verified Boot state can be one of the following:
189      * <li> {@code green} indicates that there is a full chain of trust extending from the
190      * bootloader to verified partitions including the bootloader, boot partition, and all verified
191      * partitions.
192      * <li> {@code yellow} indicates that the boot partition has been verified using the embedded
193      * certificate and the signature is valid.
194      * <li> {@code orange} indicates that the device may be freely modified. Device integrity is
195      * left to the user to verify out-of-band.
196      * <p>dm-verity mode can be one of the following:
197      * <li> {@code enforcing} indicates that the device will be restarted when corruption is
198      * detected.
199      * <li> {@code eio} indicates that an I/O error will be returned for an attempt to read
200      * corrupted data blocks.
201      * <li> {@code disabled} indicates that integrity check is disabled.
202      * For details see Verified Boot documentation.
203      */
204     public static final int TAG_OS_STARTUP = SecurityLogTags.SECURITY_OS_STARTUP;
205 
206     /**
207      * Indicates that the Android OS has shutdown. There is no extra payload in the log event.
208      */
209     public static final int TAG_OS_SHUTDOWN = SecurityLogTags.SECURITY_OS_SHUTDOWN;
210 
211     /**
212      * Indicates start-up of audit logging. There is no extra payload in the log event.
213      */
214     public static final int TAG_LOGGING_STARTED = SecurityLogTags.SECURITY_LOGGING_STARTED;
215 
216     /**
217      * Indicates shutdown of audit logging. There is no extra payload in the log event.
218      */
219     public static final int TAG_LOGGING_STOPPED = SecurityLogTags.SECURITY_LOGGING_STOPPED;
220 
221     /**
222      * Indicates that removable media has been mounted on the device. The log entry contains the
223      * following information about the event, encapsulated in an {@link Object} array and
224      * accessible via {@link SecurityEvent#getData()}:
225      * <li> [0] mount point ({@code String})
226      * <li> [1] volume label ({@code String}). Redacted to empty string on organization-owned
227      *     managed profile devices.
228      */
229     public static final int TAG_MEDIA_MOUNT = SecurityLogTags.SECURITY_MEDIA_MOUNTED;
230 
231     /**
232      * Indicates that removable media was unmounted from the device. The log entry contains the
233      * following information about the event, encapsulated in an {@link Object} array and
234      * accessible via {@link SecurityEvent#getData()}:
235      * <li> [0] mount point ({@code String})
236      * <li> [1] volume label ({@code String}). Redacted to empty string on organization-owned
237      *     managed profile devices.
238      */
239     public static final int TAG_MEDIA_UNMOUNT = SecurityLogTags.SECURITY_MEDIA_UNMOUNTED;
240 
241     /**
242      * Indicates that the audit log buffer has reached 90% of its capacity. There is no extra
243      * payload in the log event.
244      */
245     public static final int TAG_LOG_BUFFER_SIZE_CRITICAL =
246             SecurityLogTags.SECURITY_LOG_BUFFER_SIZE_CRITICAL;
247 
248     /**
249      * Indicates that an admin has set a password expiration timeout. The log entry contains the
250      * following information about the event, encapsulated in an {@link Object} array and accessible
251      * via {@link SecurityEvent#getData()}:
252      * <li> [0] admin package name ({@code String})
253      * <li> [1] admin user ID ({@code Integer})
254      * <li> [2] target user ID ({@code Integer})
255      * <li> [3] new password expiration timeout in milliseconds ({@code Long}).
256      * @see DevicePolicyManager#setPasswordExpirationTimeout(ComponentName, long)
257      */
258     public static final int TAG_PASSWORD_EXPIRATION_SET =
259             SecurityLogTags.SECURITY_PASSWORD_EXPIRATION_SET;
260 
261     /**
262      * Indicates that an admin has set a requirement for password complexity. The log entry contains
263      * the following information about the event, encapsulated in an {@link Object} array and
264      * accessible via {@link SecurityEvent#getData()}:
265      * <li> [0] admin package name ({@code String})
266      * <li> [1] admin user ID ({@code Integer})
267      * <li> [2] target user ID ({@code Integer})
268      * <li> [3] minimum password length ({@code Integer})
269      * <li> [4] password quality constraint ({@code Integer})
270      * <li> [5] minimum number of letters ({@code Integer})
271      * <li> [6] minimum number of non-letters ({@code Integer})
272      * <li> [7] minimum number of digits ({@code Integer})
273      * <li> [8] minimum number of uppercase letters ({@code Integer})
274      * <li> [9] minimum number of lowercase letters ({@code Integer})
275      * <li> [10] minimum number of symbols ({@code Integer})
276      *
277      * @see DevicePolicyManager#setPasswordMinimumLength(ComponentName, int)
278      * @see DevicePolicyManager#setPasswordQuality(ComponentName, int)
279      * @see DevicePolicyManager#setPasswordMinimumLetters(ComponentName, int)
280      * @see DevicePolicyManager#setPasswordMinimumNonLetter(ComponentName, int)
281      * @see DevicePolicyManager#setPasswordMinimumLowerCase(ComponentName, int)
282      * @see DevicePolicyManager#setPasswordMinimumUpperCase(ComponentName, int)
283      * @see DevicePolicyManager#setPasswordMinimumNumeric(ComponentName, int)
284      * @see DevicePolicyManager#setPasswordMinimumSymbols(ComponentName, int)
285      */
286     public static final int TAG_PASSWORD_COMPLEXITY_SET =
287             SecurityLogTags.SECURITY_PASSWORD_COMPLEXITY_SET;
288 
289     /**
290      * Indicates that an admin has set a password history length. The log entry contains the
291      * following information about the event encapsulated in an {@link Object} array, accessible
292      * via {@link SecurityEvent#getData()}:
293      * <li> [0] admin package name ({@code String})
294      * <li> [1] admin user ID ({@code Integer})
295      * <li> [2] target user ID ({@code Integer})
296      * <li> [3] new password history length value ({@code Integer})
297      * @see DevicePolicyManager#setPasswordHistoryLength(ComponentName, int)
298      */
299     public static final int TAG_PASSWORD_HISTORY_LENGTH_SET =
300             SecurityLogTags.SECURITY_PASSWORD_HISTORY_LENGTH_SET;
301 
302     /**
303      * Indicates that an admin has set a maximum screen lock timeout. The log entry contains the
304      * following information about the event encapsulated in an {@link Object} array, accessible
305      * via {@link SecurityEvent#getData()}:
306      * <li> [0] admin package name ({@code String})
307      * <li> [1] admin user ID ({@code Integer})
308      * <li> [2] target user ID ({@code Integer})
309      * <li> [3] new screen lock timeout in milliseconds ({@code Long})
310      * @see DevicePolicyManager#setMaximumTimeToLock(ComponentName, long)
311      */
312     public static final int TAG_MAX_SCREEN_LOCK_TIMEOUT_SET =
313             SecurityLogTags.SECURITY_MAX_SCREEN_LOCK_TIMEOUT_SET;
314 
315     /**
316      * Indicates that an admin has set a maximum number of failed password attempts before wiping
317      * data. The log entry contains the following information about the event encapsulated in an
318      * {@link Object} array, accessible via {@link SecurityEvent#getData()}:
319      * <li> [0] admin package name ({@code String})
320      * <li> [1] admin user ID ({@code Integer})
321      * <li> [2] target user ID ({@code Integer})
322      * <li> [3] new maximum number of failed password attempts ({@code Integer})
323      * @see DevicePolicyManager#setMaximumFailedPasswordsForWipe(ComponentName, int)
324      */
325     public static final int TAG_MAX_PASSWORD_ATTEMPTS_SET =
326             SecurityLogTags.SECURITY_MAX_PASSWORD_ATTEMPTS_SET;
327 
328     /**
329      * Indicates that an admin has set disabled keyguard features. The log entry contains the
330      * following information about the event encapsulated in an {@link Object} array, accessible via
331      * {@link SecurityEvent#getData()}:
332      * <li> [0] admin package name ({@code String})
333      * <li> [1] admin user ID ({@code Integer})
334      * <li> [2] target user ID ({@code Integer})
335      * <li> [3] disabled keyguard feature mask ({@code Integer}).
336      * @see DevicePolicyManager#setKeyguardDisabledFeatures(ComponentName, int)
337      */
338     public static final int TAG_KEYGUARD_DISABLED_FEATURES_SET =
339             SecurityLogTags.SECURITY_KEYGUARD_DISABLED_FEATURES_SET;
340 
341     /**
342      * Indicates that an admin remotely locked the device or profile. The log entry contains the
343      * following information about the event encapsulated in an {@link Object} array, accessible via
344      * {@link SecurityEvent#getData()}:
345      * <li> [0] admin package name ({@code String}),
346      * <li> [1] admin user ID ({@code Integer}).
347      * <li> [2] target user ID ({@code Integer})
348      */
349     public static final int TAG_REMOTE_LOCK = SecurityLogTags.SECURITY_REMOTE_LOCK;
350 
351     /**
352      * Indicates a failure to wipe device or user data. There is no extra payload in the log event.
353      */
354     public static final int TAG_WIPE_FAILURE = SecurityLogTags.SECURITY_WIPE_FAILED;
355 
356     /**
357      * Indicates that a cryptographic key was generated. The log entry contains the following
358      * information about the event, encapsulated in an {@link Object} array and accessible via
359      * {@link SecurityEvent#getData()}:
360      * <li> [0] result ({@code Integer}, 0 if operation failed, 1 if succeeded)
361      * <li> [1] alias of the key ({@code String})
362      * <li> [2] requesting process uid ({@code Integer}).
363      *
364      * If security logging is enabled on organization-owned managed profile devices, only events
365      * happening inside the managed profile will be visible.
366      */
367     public static final int TAG_KEY_GENERATED =
368             SecurityLogTags.SECURITY_KEY_GENERATED;
369 
370     /**
371      * Indicates that a cryptographic key was imported. The log entry contains the following
372      * information about the event, encapsulated in an {@link Object} array and accessible via
373      * {@link SecurityEvent#getData()}:
374      * <li> [0] result ({@code Integer}, 0 if operation failed, 1 if succeeded)
375      * <li> [1] alias of the key ({@code String})
376      * <li> [2] requesting process uid ({@code Integer}).
377      *
378      * If security logging is enabled on organization-owned managed profile devices, only events
379      * happening inside the managed profile will be visible.
380      */
381     public static final int TAG_KEY_IMPORT = SecurityLogTags.SECURITY_KEY_IMPORTED;
382 
383     /**
384      * Indicates that a cryptographic key was destroyed. The log entry contains the following
385      * information about the event, encapsulated in an {@link Object} array and accessible via
386      * {@link SecurityEvent#getData()}:
387      * <li> [0] result ({@code Integer}, 0 if operation failed, 1 if succeeded)
388      * <li> [1] alias of the key ({@code String})
389      * <li> [2] requesting process uid ({@code Integer}).
390      *
391      * If security logging is enabled on organization-owned managed profile devices, only events
392      * happening inside the managed profile will be visible.
393      */
394     public static final int TAG_KEY_DESTRUCTION = SecurityLogTags.SECURITY_KEY_DESTROYED;
395 
396     /**
397      * Indicates that a new root certificate has been installed into system's trusted credential
398      * storage. The log entry contains the following information about the event, encapsulated in an
399      * {@link Object} array and accessible via {@link SecurityEvent#getData()}:
400      * <li> [0] result ({@code Integer}, 0 if operation failed, 1 if succeeded)
401      * <li> [1] subject of the certificate ({@code String}).
402      * <li> [2] which user the certificate is installed for ({@code Integer}), only available from
403      *   version {@link android.os.Build.VERSION_CODES#R}.
404      *
405      * If security logging is enabled on organization-owned managed profile devices, only events
406      * happening inside the managed profile will be visible.
407      */
408     public static final int TAG_CERT_AUTHORITY_INSTALLED =
409             SecurityLogTags.SECURITY_CERT_AUTHORITY_INSTALLED;
410 
411     /**
412      * Indicates that a new root certificate has been removed from system's trusted credential
413      * storage. The log entry contains the following information about the event, encapsulated in an
414      * {@link Object} array and accessible via {@link SecurityEvent#getData()}:
415      * <li> [0] result ({@code Integer}, 0 if operation failed, 1 if succeeded)
416      * <li> [1] subject of the certificate ({@code String}).
417      * <li> [2] which user the certificate is removed from ({@code Integer}), only available from
418      *   version {@link android.os.Build.VERSION_CODES#R}.
419      *
420      * If security logging is enabled on organization-owned managed profile devices, only events
421      * happening inside the managed profile will be visible.
422      */
423     public static final int TAG_CERT_AUTHORITY_REMOVED =
424             SecurityLogTags.SECURITY_CERT_AUTHORITY_REMOVED;
425 
426     /**
427      * Indicates that an admin has set a user restriction. The log entry contains the following
428      * information about the event, encapsulated in an {@link Object} array and accessible via
429      * {@link SecurityEvent#getData()}:
430      * <li> [0] admin package name ({@code String})
431      * <li> [1] admin user ID ({@code Integer})
432      * <li> [2] user restriction ({@code String})
433      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
434      */
435     public static final int TAG_USER_RESTRICTION_ADDED =
436             SecurityLogTags.SECURITY_USER_RESTRICTION_ADDED;
437 
438     /**
439      * Indicates that an admin has removed a user restriction. The log entry contains the following
440      * information about the event, encapsulated in an {@link Object} array and accessible via
441      * {@link SecurityEvent#getData()}:
442      * <li> [0] admin package name ({@code String})
443      * <li> [1] admin user ID ({@code Integer})
444      * <li> [2] user restriction ({@code String})
445      * @see DevicePolicyManager#clearUserRestriction(ComponentName, String)
446      */
447     public static final int TAG_USER_RESTRICTION_REMOVED =
448             SecurityLogTags.SECURITY_USER_RESTRICTION_REMOVED;
449 
450     /**
451      * Indicates that cryptographic functionality self test has completed. The log entry contains an
452      * {@code Integer} payload, indicating the result of the test (0 if the test failed, 1 if
453      * succeeded) and accessible via {@link SecurityEvent#getData()}.
454      */
455     public static final int TAG_CRYPTO_SELF_TEST_COMPLETED =
456             SecurityLogTags.SECURITY_CRYPTO_SELF_TEST_COMPLETED;
457 
458     /**
459      * Indicates a failed cryptographic key integrity check. The log entry contains the following
460      * information about the event, encapsulated in an {@link Object} array and accessible via
461      * {@link SecurityEvent#getData()}:
462      * <li> [0] alias of the key ({@code String})
463      * <li> [1] owner application uid ({@code Integer}).
464      *
465      * If security logging is enabled on organization-owned managed profile devices, only events
466      * happening inside the managed profile will be visible.
467      */
468     public static final int TAG_KEY_INTEGRITY_VIOLATION =
469             SecurityLogTags.SECURITY_KEY_INTEGRITY_VIOLATION;
470 
471     /**
472      * Indicates a failure to validate X.509v3 certificate. The log entry contains a {@code String}
473      * payload indicating the failure reason, accessible via {@link SecurityEvent#getData()}.
474      */
475     public static final int TAG_CERT_VALIDATION_FAILURE =
476             SecurityLogTags.SECURITY_CERT_VALIDATION_FAILURE;
477 
478     /**
479      * Indicates that the admin has set policy to disable camera.
480      * The log entry contains the following information about the event, encapsulated in an
481      * {@link Object} array and accessible via {@link SecurityEvent#getData()}:
482      * <li> [0] admin package name ({@code String})
483      * <li> [1] admin user ID ({@code Integer})
484      * <li> [2] target user ID ({@code Integer})
485      * <li> [3] whether the camera is disabled or not ({@code Integer}, 1 if it's disabled,
486      *      0 if enabled)
487      */
488     public static final int TAG_CAMERA_POLICY_SET =
489             SecurityLogTags.SECURITY_CAMERA_POLICY_SET;
490 
491     /**
492      * Indicates that an admin has set a password complexity requirement, using the platform's
493      * pre-defined complexity levels. The log entry contains the following information about the
494      * event, encapsulated in an {@link Object} array and accessible via
495      * {@link SecurityEvent#getData()}:
496      * <li> [0] admin package name ({@code String})
497      * <li> [1] admin user ID ({@code Integer})
498      * <li> [2] target user ID ({@code Integer})
499      * <li> [3] Password complexity ({@code Integer})
500      *
501      * @see DevicePolicyManager#setRequiredPasswordComplexity(int)
502      */
503     public static final int TAG_PASSWORD_COMPLEXITY_REQUIRED =
504             SecurityLogTags.SECURITY_PASSWORD_COMPLEXITY_REQUIRED;
505 
506     /**
507      * Indicates that a user has just changed their lockscreen password.
508      * The log entry contains the following information about the
509      * event, encapsulated in an {@link Object} array and accessible via
510      * {@link SecurityEvent#getData()}:
511      * <li> [0] complexity for the new password ({@code Integer})
512      * <li> [1] target user ID ({@code Integer})
513      *
514      * <p>Password complexity levels are defined as in
515      * {@link DevicePolicyManager#getPasswordComplexity()}
516      */
517     public static final int TAG_PASSWORD_CHANGED = SecurityLogTags.SECURITY_PASSWORD_CHANGED;
518 
519     /**
520      * Indicates that an event occurred as the device attempted to connect to
521      * a WiFi network. The log entry contains the following information about the
522      * event, encapsulated in an {@link Object} array and accessible via
523      * {@link SecurityEvent#getData()}:
524      * <li> [0] Last 2 octets of the network BSSID ({@code String}, in the form "xx:xx:xx:xx:AA:BB")
525      * <li> [1] Type of event that occurred ({@code String}). Event types are CONNECTED,
526      *      DISCONNECTED, ASSOCIATING, ASSOCIATED, EAP_METHOD_SELECTED, EAP_FAILURE,
527      *      SSID_TEMP_DISABLED, and OPEN_SSL_FAILURE.
528      * <li> [2] Optional human-readable failure reason, empty string if none ({@code String})
529      */
530     public static final int TAG_WIFI_CONNECTION = SecurityLogTags.SECURITY_WIFI_CONNECTION;
531 
532     /**
533      * Indicates that the device disconnects from a connected WiFi network.
534      * The log entry contains the following information about the
535      * event, encapsulated in an {@link Object} array and accessible via
536      * {@link SecurityEvent#getData()}:
537      * <li> [0] Last 2 octets of the network BSSID ({@code String}, in the form "xx:xx:xx:xx:AA:BB")
538      * <li> [1] Optional human-readable disconnection reason, empty string if none ({@code String})
539      */
540     public static final int TAG_WIFI_DISCONNECTION = SecurityLogTags.SECURITY_WIFI_DISCONNECTION;
541 
542     /**
543      * Indicates that the device attempts to connect to a Bluetooth device.
544      * The log entry contains the following information about the
545      * event, encapsulated in an {@link Object} array and accessible via
546      * {@link SecurityEvent#getData()}:
547      * <li> [0] The MAC address of the Bluetooth device ({@code String})
548      * <li> [1] Whether the connection is successful ({@code Integer}, 1 if successful, 0 otherwise)
549      * <li> [2] Optional human-readable failure reason, empty string if none ({@code String})
550      */
551     public static final int TAG_BLUETOOTH_CONNECTION =
552             SecurityLogTags.SECURITY_BLUETOOTH_CONNECTION;
553 
554     /**
555      * Indicates that the device disconnects from a connected Bluetooth device.
556      * The log entry contains the following information about the
557      * event, encapsulated in an {@link Object} array and accessible via
558      * {@link SecurityEvent#getData()}:
559      * <li> [0] The MAC address of the connected Bluetooth device ({@code String})
560      * <li> [1] Optional human-readable disconnection reason, empty string if none ({@code String})
561      */
562     public static final int TAG_BLUETOOTH_DISCONNECTION =
563             SecurityLogTags.SECURITY_BLUETOOTH_DISCONNECTION;
564 
565     /**
566      * Event severity level indicating that the event corresponds to normal workflow.
567      */
568     public static final int LEVEL_INFO = 1;
569 
570     /**
571      * Event severity level indicating that the event may require admin attention.
572      */
573     public static final int LEVEL_WARNING = 2;
574 
575     /**
576      * Event severity level indicating that the event requires urgent admin action.
577      */
578     public static final int LEVEL_ERROR = 3;
579 
580     /**
581      * Returns if security logging is enabled. Log producers should only write new logs if this is
582      * true. Under the hood this is the logical AND of whether device owner exists and whether
583      * it enables logging by setting the system property {@link #PROPERTY_LOGGING_ENABLED}.
584      * @hide
585      */
isLoggingEnabled()586     public static native boolean isLoggingEnabled();
587 
588     /**
589      * @hide
590      */
setLoggingEnabledProperty(boolean enabled)591     public static void setLoggingEnabledProperty(boolean enabled) {
592         SystemProperties.set(PROPERTY_LOGGING_ENABLED, enabled ? "true" : "false");
593     }
594 
595     /**
596      * @hide
597      */
getLoggingEnabledProperty()598     public static boolean getLoggingEnabledProperty() {
599         return SystemProperties.getBoolean(PROPERTY_LOGGING_ENABLED, false);
600     }
601 
602     /**
603      * A class representing a security event log entry.
604      */
605     public static final class SecurityEvent implements Parcelable {
606         private Event mEvent;
607         private long mId;
608 
609         /**
610          * Constructor used by native classes to generate SecurityEvent instances.
611          * @hide
612          */
613         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
SecurityEvent(byte[] data)614         /* package */ SecurityEvent(byte[] data) {
615             this(0, data);
616         }
617 
618         /**
619          * Constructor used by Parcelable.Creator to generate SecurityEvent instances.
620          * @hide
621          */
SecurityEvent(Parcel source)622         /* package */ SecurityEvent(Parcel source) {
623             this(source.readLong(), source.createByteArray());
624         }
625 
626         /** @hide */
627         @TestApi
SecurityEvent(long id, byte[] data)628         public SecurityEvent(long id, byte[] data) {
629             mId = id;
630             mEvent = Event.fromBytes(data);
631         }
632 
633         /**
634          * Returns the timestamp in nano seconds when this event was logged.
635          */
getTimeNanos()636         public long getTimeNanos() {
637             return mEvent.getTimeNanos();
638         }
639 
640         /**
641          * Returns the tag of this log entry, which specifies entry's semantics.
642          */
getTag()643         public @SecurityLogTag int getTag() {
644             return mEvent.getTag();
645         }
646 
647         /**
648          * Returns the payload contained in this log entry or {@code null} if there is no payload.
649          */
getData()650         public Object getData() {
651             return mEvent.getData();
652         }
653 
654         /** @hide */
getIntegerData(int index)655         public int getIntegerData(int index) {
656             return (Integer) ((Object[]) mEvent.getData())[index];
657         }
658 
659         /** @hide */
getStringData(int index)660         public String getStringData(int index) {
661             return (String) ((Object[]) mEvent.getData())[index];
662         }
663 
664         /**
665          * @hide
666          */
setId(long id)667         public void setId(long id) {
668             this.mId = id;
669         }
670 
671         /**
672          * Returns the id of the event, where the id monotonically increases for each event. The id
673          * is reset when the device reboots, and when security logging is enabled.
674          */
getId()675         public long getId() {
676             return mId;
677         }
678 
679         /**
680          * Returns severity level for the event.
681          */
getLogLevel()682         public @SecurityLogLevel int getLogLevel() {
683             switch (getTag()) {
684                 case TAG_ADB_SHELL_INTERACTIVE:
685                 case TAG_ADB_SHELL_CMD:
686                 case TAG_SYNC_RECV_FILE:
687                 case TAG_SYNC_SEND_FILE:
688                 case TAG_APP_PROCESS_START:
689                 case TAG_KEYGUARD_DISMISSED:
690                 case TAG_KEYGUARD_SECURED:
691                 case TAG_OS_STARTUP:
692                 case TAG_OS_SHUTDOWN:
693                 case TAG_LOGGING_STARTED:
694                 case TAG_LOGGING_STOPPED:
695                 case TAG_MEDIA_MOUNT:
696                 case TAG_MEDIA_UNMOUNT:
697                 case TAG_PASSWORD_EXPIRATION_SET:
698                 case TAG_PASSWORD_COMPLEXITY_SET:
699                 case TAG_PASSWORD_HISTORY_LENGTH_SET:
700                 case TAG_MAX_SCREEN_LOCK_TIMEOUT_SET:
701                 case TAG_MAX_PASSWORD_ATTEMPTS_SET:
702                 case TAG_USER_RESTRICTION_ADDED:
703                 case TAG_USER_RESTRICTION_REMOVED:
704                 case TAG_CAMERA_POLICY_SET:
705                 case TAG_PASSWORD_COMPLEXITY_REQUIRED:
706                 case TAG_PASSWORD_CHANGED:
707                     return LEVEL_INFO;
708                 case TAG_CERT_AUTHORITY_REMOVED:
709                 case TAG_CRYPTO_SELF_TEST_COMPLETED:
710                     return getSuccess() ? LEVEL_INFO : LEVEL_ERROR;
711                 case TAG_CERT_AUTHORITY_INSTALLED:
712                 case TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT:
713                 case TAG_KEY_IMPORT:
714                 case TAG_KEY_DESTRUCTION:
715                 case TAG_KEY_GENERATED:
716                     return getSuccess() ? LEVEL_INFO : LEVEL_WARNING;
717                 case TAG_LOG_BUFFER_SIZE_CRITICAL:
718                 case TAG_WIPE_FAILURE:
719                 case TAG_KEY_INTEGRITY_VIOLATION:
720                     return LEVEL_ERROR;
721                 case TAG_CERT_VALIDATION_FAILURE:
722                     return LEVEL_WARNING;
723                 default:
724                     return LEVEL_INFO;
725             }
726         }
727 
728         // Success/failure if present is encoded as an integer in the first (0th) element of data.
getSuccess()729         private boolean getSuccess() {
730             final Object data = getData();
731             if (data == null || !(data instanceof Object[])) {
732                 return false;
733             }
734 
735             final Object[] array = (Object[]) data;
736             return array.length >= 1 && array[0] instanceof Integer && (Integer) array[0] != 0;
737         }
738 
739         /**
740          * Returns a copy of the security event suitable to be consumed by the provided user.
741          * This method will either return the original event itself if the event does not contain
742          * any sensitive data; or a copy of itself but with sensitive information redacted; or
743          * {@code null} if the entire event should not be accessed by the given user.
744          *
745          * @param accessingUser which user this security event is to be accessed, must be a
746          *     concrete user id.
747          * @hide
748          */
redact(int accessingUser)749         public SecurityEvent redact(int accessingUser) {
750             // Which user the event is associated with, for the purpose of log redaction.
751             final int userId;
752             switch (getTag()) {
753                 case SecurityLog.TAG_ADB_SHELL_CMD:
754                     return new SecurityEvent(getId(), mEvent.withNewData("").getBytes());
755                 case SecurityLog.TAG_MEDIA_MOUNT:
756                 case SecurityLog.TAG_MEDIA_UNMOUNT:
757                     // Partial redaction
758                     String mountPoint;
759                     try {
760                         mountPoint = getStringData(0);
761                     } catch (Exception e) {
762                         return null;
763                     }
764                     return new SecurityEvent(getId(),
765                             mEvent.withNewData(new Object[] {mountPoint, ""}).getBytes());
766                 case SecurityLog.TAG_APP_PROCESS_START:
767                     try {
768                         userId = UserHandle.getUserId(getIntegerData(2));
769                     } catch (Exception e) {
770                         return null;
771                     }
772                     break;
773                 case SecurityLog.TAG_CERT_AUTHORITY_INSTALLED:
774                 case SecurityLog.TAG_CERT_AUTHORITY_REMOVED:
775                     try {
776                         userId = getIntegerData(2);
777                     } catch (Exception e) {
778                         return null;
779                     }
780                     break;
781                 case SecurityLog.TAG_KEY_GENERATED:
782                 case SecurityLog.TAG_KEY_IMPORT:
783                 case SecurityLog.TAG_KEY_DESTRUCTION:
784                     try {
785                         userId = UserHandle.getUserId(getIntegerData(2));
786                     } catch (Exception e) {
787                         return null;
788                     }
789                     break;
790                 case SecurityLog.TAG_KEY_INTEGRITY_VIOLATION:
791                     try {
792                         userId = UserHandle.getUserId(getIntegerData(1));
793                     } catch (Exception e) {
794                         return null;
795                     }
796                     break;
797                 case SecurityLog.TAG_PASSWORD_CHANGED:
798                     try {
799                         userId = getIntegerData(1);
800                     } catch (Exception e) {
801                         return null;
802                     }
803                     break;
804                 default:
805                     userId = UserHandle.USER_NULL;
806             }
807             // If the event is not user-specific, or matches the accessing user, return it
808             // unmodified, else redact by returning null
809             if (userId == UserHandle.USER_NULL || accessingUser == userId) {
810                 return this;
811             } else {
812                 return null;
813             }
814         }
815 
816         @Override
describeContents()817         public int describeContents() {
818             return 0;
819         }
820 
821         @Override
writeToParcel(Parcel dest, int flags)822         public void writeToParcel(Parcel dest, int flags) {
823             dest.writeLong(mId);
824             dest.writeByteArray(mEvent.getBytes());
825         }
826 
827         public static final @android.annotation.NonNull Parcelable.Creator<SecurityEvent> CREATOR =
828                 new Parcelable.Creator<SecurityEvent>() {
829             @Override
830             public SecurityEvent createFromParcel(Parcel source) {
831                 return new SecurityEvent(source);
832             }
833 
834             @Override
835             public SecurityEvent[] newArray(int size) {
836                 return new SecurityEvent[size];
837             }
838         };
839 
840         /**
841          * @hide
842          */
843         @Override
equals(@ullable Object o)844         public boolean equals(@Nullable Object o) {
845             if (this == o) return true;
846             if (o == null || getClass() != o.getClass()) return false;
847             SecurityEvent other = (SecurityEvent) o;
848             return mEvent.equals(other.mEvent) && mId == other.mId;
849         }
850 
851         /**
852          * @hide
853          */
854         @Override
hashCode()855         public int hashCode() {
856             return Objects.hash(mEvent, mId);
857         }
858 
859         /** @hide */
eventEquals(SecurityEvent other)860         public boolean eventEquals(SecurityEvent other) {
861             return other != null && mEvent.equals(other.mEvent);
862         }
863     }
864 
865     /**
866      * Redacts events in-place according to which user will consume the events.
867      *
868      * @param accessingUser which user will consume the redacted events, or UserHandle.USER_ALL if
869      *     redaction should be skipped.
870      * @hide
871      */
redactEvents(ArrayList<SecurityEvent> logList, int accessingUser)872     public static void redactEvents(ArrayList<SecurityEvent> logList, int accessingUser) {
873         if (accessingUser == UserHandle.USER_ALL) return;
874         int end = 0;
875         for (int i = 0; i < logList.size(); i++) {
876             SecurityEvent event = logList.get(i);
877             event = event.redact(accessingUser);
878             if (event != null) {
879                 logList.set(end, event);
880                 end++;
881             }
882         }
883         for (int i = logList.size() - 1; i >= end; i--) {
884             logList.remove(i);
885         }
886     }
887 
888     /**
889      * Retrieve all security logs and return immediately.
890      * @hide
891      */
readEvents(Collection<SecurityEvent> output)892     public static native void readEvents(Collection<SecurityEvent> output) throws IOException;
893 
894     /**
895      * Retrieve all security logs since the given timestamp in nanoseconds and return immediately.
896      * @hide
897      */
readEventsSince(long timestamp, Collection<SecurityEvent> output)898     public static native void readEventsSince(long timestamp, Collection<SecurityEvent> output)
899             throws IOException;
900 
901     /**
902      * Retrieve all security logs before the last reboot. May return corrupted data due to
903      * unreliable pstore.
904      * @hide
905      */
readPreviousEvents(Collection<SecurityEvent> output)906     public static native void readPreviousEvents(Collection<SecurityEvent> output)
907             throws IOException;
908 
909     /**
910      * Retrieve all security logs whose timestamp is equal to or greater than the given timestamp in
911      * nanoseconds. This method will block until either the last log earlier than the given
912      * timestamp is about to be pruned, or after a 2-hour timeout has passed.
913      * @hide
914      */
readEventsOnWrapping(long timestamp, Collection<SecurityEvent> output)915     public static native void readEventsOnWrapping(long timestamp, Collection<SecurityEvent> output)
916             throws IOException;
917 
918     /**
919      * Write a log entry to the underlying storage, with several payloads.
920      * Supported types of payload are: integer, long, float, string plus array of supported types.
921      *
922      * <p>Security log is part of Android's device management capability that tracks
923      * security-sensitive events for auditing purposes.
924      *
925      * @param tag the tag ID of the security event
926      * @param payloads a list of payload values. Each tag dictates the expected payload types
927      *                 and their meanings
928      * @see DevicePolicyManager#setSecurityLoggingEnabled(ComponentName, boolean)
929      *
930      * @hide
931      */
932     // TODO(b/218658622): enforce WRITE_SECURITY_LOG in logd.
933     @SystemApi
934     @RequiresPermission(Manifest.permission.WRITE_SECURITY_LOG)
writeEvent(@ecurityLogTag int tag, @NonNull Object... payloads)935     public static native int writeEvent(@SecurityLogTag int tag, @NonNull Object... payloads);
936 }
937