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