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.annotation.IntDef; 20 import android.os.Parcel; 21 import android.os.Parcelable; 22 import android.os.SystemProperties; 23 import android.util.EventLog.Event; 24 25 import java.io.IOException; 26 import java.lang.annotation.Retention; 27 import java.lang.annotation.RetentionPolicy; 28 import java.util.Collection; 29 30 /** 31 * Definitions for working with security logs. 32 * 33 * <p>Device owner apps can control the logging with 34 * {@link DevicePolicyManager#setSecurityLoggingEnabled}. When security logs are enabled, device 35 * owner apps receive periodic callbacks from {@link DeviceAdminReceiver#onSecurityLogsAvailable}, 36 * at which time new batch of logs can be collected via 37 * {@link DevicePolicyManager#retrieveSecurityLogs}. {@link SecurityEvent} describes the type and 38 * format of security logs being collected. 39 */ 40 public class SecurityLog { 41 42 private static final String PROPERTY_LOGGING_ENABLED = "persist.logd.security"; 43 44 /** @hide */ 45 @Retention(RetentionPolicy.SOURCE) 46 @IntDef({TAG_ADB_SHELL_INTERACTIVE, TAG_ADB_SHELL_CMD, TAG_SYNC_RECV_FILE, TAG_SYNC_SEND_FILE, 47 TAG_APP_PROCESS_START, TAG_KEYGUARD_DISMISSED, TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT, 48 TAG_KEYGUARD_SECURED}) 49 public @interface SECURITY_LOG_TAG {} 50 51 /** 52 * Indicate that an ADB interactive shell was opened via "adb shell". 53 * There is no extra payload in the log event. 54 */ 55 public static final int TAG_ADB_SHELL_INTERACTIVE = 56 SecurityLogTags.SECURITY_ADB_SHELL_INTERACTIVE; 57 /** 58 * Indicate that an shell command was issued over ADB via "adb shell command" 59 * The log entry contains a string data of the shell command, accessible via 60 * {@link SecurityEvent#getData()} 61 */ 62 public static final int TAG_ADB_SHELL_CMD = SecurityLogTags.SECURITY_ADB_SHELL_COMMAND; 63 /** 64 * Indicate that a file was pulled from the device via the adb daemon, for example via 65 * "adb pull". The log entry contains a string data of the path of the pulled file, 66 * accessible via {@link SecurityEvent#getData()} 67 */ 68 public static final int TAG_SYNC_RECV_FILE = SecurityLogTags.SECURITY_ADB_SYNC_RECV; 69 /** 70 * Indicate that a file was pushed to the device via the adb daemon, for example via 71 * "adb push". The log entry contains a string data of the destination path of the 72 * pushed file, accessible via {@link SecurityEvent#getData()} 73 */ 74 public static final int TAG_SYNC_SEND_FILE = SecurityLogTags.SECURITY_ADB_SYNC_SEND; 75 /** 76 * Indicate that an app process was started. The log entry contains the following 77 * information about the process encapsulated in an {@link Object} array, accessible via 78 * {@link SecurityEvent#getData()}: 79 * process name (String), exact start time (long), app Uid (integer), app Pid (integer), 80 * seinfo tag (String), SHA-256 hash of the base APK in hexadecimal (String) 81 */ 82 public static final int TAG_APP_PROCESS_START = SecurityLogTags.SECURITY_APP_PROCESS_START; 83 /** 84 * Indicate that keyguard is being dismissed. 85 * There is no extra payload in the log event. 86 */ 87 public static final int TAG_KEYGUARD_DISMISSED = 88 SecurityLogTags.SECURITY_KEYGUARD_DISMISSED; 89 /** 90 * Indicate that there has been an authentication attempt to dismiss the keyguard. The log entry 91 * contains the following information about the attempt encapsulated in an {@link Object} array, 92 * accessible via {@link SecurityEvent#getData()}: 93 * attempt result (integer, 1 for successful, 0 for unsuccessful), strength of auth method 94 * (integer, 1 if strong auth method was used, 0 otherwise) 95 */ 96 public static final int TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT = 97 SecurityLogTags.SECURITY_KEYGUARD_DISMISS_AUTH_ATTEMPT; 98 /** 99 * Indicate that the device has been locked, either by user or by timeout. 100 * There is no extra payload in the log event. 101 */ 102 public static final int TAG_KEYGUARD_SECURED = SecurityLogTags.SECURITY_KEYGUARD_SECURED; 103 104 /** 105 * Returns if security logging is enabled. Log producers should only write new logs if this is 106 * true. Under the hood this is the logical AND of whether device owner exists and whether 107 * it enables logging by setting the system property {@link #PROPERTY_LOGGING_ENABLED}. 108 * @hide 109 */ isLoggingEnabled()110 public static native boolean isLoggingEnabled(); 111 112 /** 113 * @hide 114 */ setLoggingEnabledProperty(boolean enabled)115 public static void setLoggingEnabledProperty(boolean enabled) { 116 SystemProperties.set(PROPERTY_LOGGING_ENABLED, enabled ? "true" : "false"); 117 } 118 119 /** 120 * @hide 121 */ getLoggingEnabledProperty()122 public static boolean getLoggingEnabledProperty() { 123 return SystemProperties.getBoolean(PROPERTY_LOGGING_ENABLED, false); 124 } 125 126 /** 127 * A class representing a security event log entry. 128 */ 129 public static final class SecurityEvent implements Parcelable { 130 private Event mEvent; 131 132 /** @hide */ SecurityEvent(byte[] data)133 /*package*/ SecurityEvent(byte[] data) { 134 mEvent = Event.fromBytes(data); 135 } 136 137 /** 138 * Returns the timestamp in nano seconds when this event was logged. 139 */ getTimeNanos()140 public long getTimeNanos() { 141 return mEvent.getTimeNanos(); 142 } 143 144 /** 145 * Returns the tag of this log entry, which specifies entry's semantics. 146 * Could be one of {@link SecurityLog#TAG_SYNC_RECV_FILE}, 147 * {@link SecurityLog#TAG_SYNC_SEND_FILE}, {@link SecurityLog#TAG_ADB_SHELL_CMD}, 148 * {@link SecurityLog#TAG_ADB_SHELL_INTERACTIVE}, {@link SecurityLog#TAG_APP_PROCESS_START}, 149 * {@link SecurityLog#TAG_KEYGUARD_DISMISSED}, {@link SecurityLog#TAG_KEYGUARD_SECURED}, 150 * {@link SecurityLog#TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT}. 151 */ getTag()152 public @SECURITY_LOG_TAG int getTag() { 153 return mEvent.getTag(); 154 } 155 156 /** 157 * Returns the payload contained in this log entry or {@code null} if there is no payload. 158 */ getData()159 public Object getData() { 160 return mEvent.getData(); 161 } 162 163 @Override describeContents()164 public int describeContents() { 165 return 0; 166 } 167 168 @Override writeToParcel(Parcel dest, int flags)169 public void writeToParcel(Parcel dest, int flags) { 170 dest.writeByteArray(mEvent.getBytes()); 171 } 172 173 public static final Parcelable.Creator<SecurityEvent> CREATOR = 174 new Parcelable.Creator<SecurityEvent>() { 175 @Override 176 public SecurityEvent createFromParcel(Parcel source) { 177 return new SecurityEvent(source.createByteArray()); 178 } 179 180 @Override 181 public SecurityEvent[] newArray(int size) { 182 return new SecurityEvent[size]; 183 } 184 }; 185 186 /** 187 * @hide 188 */ 189 @Override equals(Object o)190 public boolean equals(Object o) { 191 if (this == o) return true; 192 if (o == null || getClass() != o.getClass()) return false; 193 SecurityEvent other = (SecurityEvent) o; 194 return mEvent.equals(other.mEvent); 195 } 196 197 /** 198 * @hide 199 */ 200 @Override hashCode()201 public int hashCode() { 202 return mEvent.hashCode(); 203 } 204 } 205 /** 206 * Retrieve all security logs and return immediately. 207 * @hide 208 */ readEvents(Collection<SecurityEvent> output)209 public static native void readEvents(Collection<SecurityEvent> output) throws IOException; 210 211 /** 212 * Retrieve all security logs since the given timestamp in nanoseconds and return immediately. 213 * @hide 214 */ readEventsSince(long timestamp, Collection<SecurityEvent> output)215 public static native void readEventsSince(long timestamp, Collection<SecurityEvent> output) 216 throws IOException; 217 218 /** 219 * Retrieve all security logs before the last reboot. May return corrupted data due to 220 * unreliable pstore. 221 * @hide 222 */ readPreviousEvents(Collection<SecurityEvent> output)223 public static native void readPreviousEvents(Collection<SecurityEvent> output) 224 throws IOException; 225 226 /** 227 * Retrieve all security logs whose timestamp (in nanosceonds) is equal to or greater than the 228 * given timestamp. This method will block until either the last log earlier than the given 229 * timestamp is about to be pruned, or after a 2-hour timeout has passed. 230 * @hide 231 */ readEventsOnWrapping(long timestamp, Collection<SecurityEvent> output)232 public static native void readEventsOnWrapping(long timestamp, Collection<SecurityEvent> output) 233 throws IOException; 234 235 /** 236 * Write a log entry to the underlying storage, with a string payload. 237 * @hide 238 */ writeEvent(int tag, String str)239 public static native int writeEvent(int tag, String str); 240 241 /** 242 * Write a log entry to the underlying storage, with several payloads. 243 * Supported types of payload are: integer, long, float, string plus array of supported types. 244 * @hide 245 */ writeEvent(int tag, Object... payloads)246 public static native int writeEvent(int tag, Object... payloads); 247 } 248