Home | History | Annotate | Download | only in admin
      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      */
    100     public static native boolean isLoggingEnabled();
    101 
    102     /**
    103      * @hide
    104      */
    105     public static void setLoggingEnabledProperty(boolean enabled) {
    106         SystemProperties.set(PROPERTY_LOGGING_ENABLED, enabled ? "true" : "false");
    107     }
    108 
    109     /**
    110      * @hide
    111      */
    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 */
    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          */
    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          */
    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          */
    150         public Object getData() {
    151             return mEvent.getData();
    152         }
    153 
    154         @Override
    155         public int describeContents() {
    156             return 0;
    157         }
    158 
    159         @Override
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    218     public static native int writeEvent(int tag, Object... payloads);
    219 }
    220