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