|
|
| [Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] |
From 56861e056337197bdb55cd413c1d410b69ff1e1c Mon Sep 17 00:00:00 2001
From: William Roberts <w.roberts@xxxxxxxxxxxxxxx>
Date: Fri, 23 Mar 2012 18:20:38 -0700
Subject: [PATCH 1/2] AVC Denied message parsing framework in place.
---
jni/Android.mk | 13 +
jni/klogctl.c | 28 ++
jni/klogctl.h | 22 ++
project.properties | 2 +-
src/com/android/seandroid_manager/AVCCallback.java | 7 +
.../seandroid_manager/AVCDeniedMessage.java | 303 ++++++++++++++++++++
src/com/android/seandroid_manager/AVCReader.java | 87 ++++++
src/com/android/seandroid_manager/KLogCtl.java | 40 +++
.../seandroid_manager/SEAndroidManager.java | 24 ++-
9 files changed, 523 insertions(+), 3 deletions(-)
create mode 100644 jni/Android.mk
create mode 100644 jni/klogctl.c
create mode 100644 jni/klogctl.h
create mode 100644 src/com/android/seandroid_manager/AVCCallback.java
create mode 100644 src/com/android/seandroid_manager/AVCDeniedMessage.java
create mode 100644 src/com/android/seandroid_manager/AVCReader.java
create mode 100644 src/com/android/seandroid_manager/KLogCtl.java
diff --git a/jni/Android.mk b/jni/Android.mk
new file mode 100644
index 0000000..45948d2
--- /dev/null
+++ b/jni/Android.mk
@@ -0,0 +1,13 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libjni_klogctl
+LOCAL_SRC_FILES := klogctl.c
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SHARED_LIBRARIES := liblog
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/jni/klogctl.c b/jni/klogctl.c
new file mode 100644
index 0000000..1f36e5c
--- /dev/null
+++ b/jni/klogctl.c
@@ -0,0 +1,28 @@
+#include <string.h>
+#include <jni.h>
+#include <errno.h>
+
+#define LOG_TAG "klogctl"
+
+ #include <cutils/log.h>
+#include "klogctl.h"
+
+extern int klogctl(int type, char *buf, int length);
+
+JNIEXPORT
+jint
+JNICALL
+Java_com_android_seandroid_1manager_KLogCtl_kLogCtl(JNIEnv *env, jclass thiz, jint type, jbyteArray buf, jint length) {
+
+ jint error;
+ jboolean is_copy;
+ jbyte *bytes = (buf) ? (*env)->GetByteArrayElements(env, buf, &is_copy) : NULL;
+
+ error = klogctl(type, (char *)bytes, length);
+
+ if(bytes) {
+ (*env)->ReleaseByteArrayElements(env, buf, bytes, 0);
+ }
+ return (error != -1) ? error : errno;
+}
+
diff --git a/jni/klogctl.h b/jni/klogctl.h
new file mode 100644
index 0000000..5496263
--- /dev/null
+++ b/jni/klogctl.h
@@ -0,0 +1,22 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_android_seandroid_manager_KLogCtl */
+
+#ifndef _Included_com_android_seandroid_manager_KLogCtl
+#define _Included_com_android_seandroid_manager_KLogCtl
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_android_seandroid_manager_KLogCtl
+ * Method: kLogCtl
+ * Signature: (I[BI)I
+ */
+JNIEXPORT jint JNICALL Java_com_android_seandroid_1manager_KLogCtl_kLogCtl
+ (JNIEnv *, jclass, jint, jbyteArray, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/project.properties b/project.properties
index b904742..8da376a 100644
--- a/project.properties
+++ b/project.properties
@@ -8,4 +8,4 @@
# project structure.
# Project target.
-target=android-13
+target=android-15
diff --git a/src/com/android/seandroid_manager/AVCCallback.java b/src/com/android/seandroid_manager/AVCCallback.java
new file mode 100644
index 0000000..34d8632
--- /dev/null
+++ b/src/com/android/seandroid_manager/AVCCallback.java
@@ -0,0 +1,7 @@
+package com.android.seandroid_manager;
+
+public interface AVCCallback {
+
+ public void handleAVCEvent(AVCDeniedMessage message);
+
+}
diff --git a/src/com/android/seandroid_manager/AVCDeniedMessage.java b/src/com/android/seandroid_manager/AVCDeniedMessage.java
new file mode 100644
index 0000000..e5070da
--- /dev/null
+++ b/src/com/android/seandroid_manager/AVCDeniedMessage.java
@@ -0,0 +1,303 @@
+package com.android.seandroid_manager;
+
+import android.util.Log;
+
+/**
+ *
+ * The class parses a raw kmsg into a formated AVC denied message.
+ *
+ */
+public class AVCDeniedMessage {
+
+ private String logTag="AVCDeniedMessage";
+
+ private String message = null;
+ private String time = null;
+ private String name = null;
+ private String pid = null;
+ private String path = null;
+ private String command = null;
+ private String capability = null;
+ private String scontext = null;
+ private String tcontext = null;
+ private String tclass = null;
+ private String dev = null;
+ private String inode = null;
+
+ AVCDeniedMessage() { }
+
+ /** Constructs a new AVCDenied object from an avc denied log line in kmsg.
+ *
+ * @param message
+ * The message obtained from dmesg, ie the line that contains the avc denied message.
+ */
+ AVCDeniedMessage(String message) {
+ this.message = message;
+ parse();
+ }
+
+ /** Set a new message into an AVCDenied message.
+ *
+ * @param message
+ * The message obtained from dmesg, ie the line that contains the avc denied message.
+ */
+ public void setMessage(String message) {
+ this.message=message;
+ parse();
+ }
+
+ /** Gets the device field from the AVC denied message.
+ *
+ * @return
+ * The device field or null if not set or null if object is not valid.
+ */
+ public String getDev() {
+
+ return dev;
+ }
+
+ /** Gets the ino field out of the AVC denied message.
+ *
+ * @return
+ * return inode number or null if not set or null if object is not valid.
+ */
+ public String getInode() {
+
+ return inode;
+ }
+
+ /** Gets the name of the process out of the AVC denied message.
+ *
+ * @return
+ * The process name, or null if object is not valid.
+ */
+ public String getName() {
+
+ return name;
+ }
+
+ /** Gets the time field out of the AVC denied message.
+ *
+ * @return
+ * The time field in kernel log format (Ticks since boot), or null if object is not valid.
+ */
+ public String getTime() {
+
+ return time;
+ }
+
+ /** Gets the PID field out of the AVC denied message.
+ *
+ * @return
+ * PID or null if object is not valid.
+ */
+ public String getPid() {
+
+ return pid;
+ }
+
+ /** Gets the path field out of the AVC denied message.
+ *
+ * @return
+ * Path or null if not set or null if object is not valid.
+ */
+ public String getPath() {
+
+ return path;
+ }
+
+ /** Gets the comm field out of the AVC denied message.
+ *
+ * @return
+ * comm or null if not set or null if object is not valid.
+ */
+ public String getCommand() {
+
+ return command;
+ }
+
+ /** Gets the scontext field out of the AVC denied message.
+ *
+ * @return
+ * scontext null if object is not valid.
+ */
+ public String getSContext() {
+
+ return scontext;
+ }
+
+ /** Gets the tcontext field out of the AVC denied message.
+ *
+ * @return
+ * tcontext or null if object is not valid.
+ */
+ public String getTContext() {
+
+ return tcontext;
+ }
+
+ /** Gets the tclass field out of the AVC denied message.
+ *
+ * @return
+ * tclass or null if object is not valid.
+ */
+ public String getTClass() {
+
+ return tclass;
+ }
+
+ /** Gets the cap field out of the AVC denied message.
+ *
+ * @return
+ * cap or null if not set or null if object is not valid.
+ */
+ public String getCapability() {
+
+ return capability;
+ }
+
+ /** Gets the raw message set in the constructor.
+ *
+ * @return
+ * raw message.
+ */
+ public String getRawMessage() {
+
+ return message;
+ }
+
+ /** Tests whether or not the object is valid or not.
+ *
+ * Tests to see if the message passed during the constructor is a properly
+ * formated avc denied message.
+ *
+ * @return
+ * True if it is valid, False if it is not valid.
+ */
+ public boolean isValid() {
+ return (message != null);
+ }
+
+ /** Returns a formated AVC denied message.
+ *
+ * @return
+ * A formated AVC denied message.
+ */
+ public String toString() {
+
+ String output = null;
+
+ if(this.isValid()) {
+ output += "Time: " + time;
+ output += " Process: " + name;
+ output += " PID: " + pid;
+ output += " Command: " + command;
+
+ if(message.length() == 20) {
+ output += " Path: " + path;
+ output += " Dev: " + dev;
+ output += " Inode: " + inode;
+ }
+ else if(message.length() == 19) {
+ output += " Capability: " + capability;
+ }
+ else if(message.length() == 18){
+ output += " Name: " + name;
+ }
+
+ output += " SContext: " + scontext;
+ output += " TContext: " + tcontext;
+ output += " TClass: " + tclass;
+ }
+
+ return output;
+ }
+
+ /** Parse this.message and store the formatted data.
+ *
+ */
+ private void parse() {
+
+ /*
+ * After splitting the AVC denied message around " " (space), the message has the following
+ * format in the array.
+ *
+ * For AVC messages with a length of 20, the format is as follows:
+ * 0 --> time
+ * 8 --> process_name
+ * 12 pid=xxx
+ * 13 comm=xxx
+ * ----------------------common
+ * 14 path=xxx
+ * 15 dev=xxx
+ * 16 ino=xxx
+ * 17 scontext=xxx
+ * 18 tcontext=xxx
+ * 19 tclass=xxx
+ *
+ * For AVC messages with a length of 19, the format is as follows:
+ * 0 --> time
+ * 8 --> process_name
+ * 12 pid=xxx
+ * 13 comm=xxx
+ * ----------------------common
+ * 14 name=xxx
+ * 15 scontext=xxx
+ * 16 tcontext=xxx
+ * 17 tclass=xxx
+ *
+ * For AVC messages with a length of 18, the format is as follows:
+ * 0 --> time
+ * 8 --> process_name
+ * 12 pid=xxx
+ * 13 comm=xxx
+ * ----------------------common
+ * 14 name=xxx
+ * 15 scontext=xxx
+ * 16 tcontext=xxx
+ * 17 tclass=xxx
+ */
+ String subparts[] = message.split(" ");
+
+ /*Common*/
+ time = subparts[0].substring(subparts[0].indexOf('[')+1, subparts[0].indexOf(']')); /*<5>[85474.589385]*/
+ name = subparts[8];
+ pid = subparts[12].split("=")[1];
+ command = subparts[13].split("=")[1];
+
+ /*Length 20*/
+ if(subparts.length == 20) {
+ path = subparts[14].split("=")[1];
+ dev = subparts[15].split("=")[1];
+ inode = subparts[16].split("=")[1];
+ scontext = subparts[17].split("=")[1];
+ tcontext = subparts[18].split("=")[1];
+ tclass = subparts[19].split("=")[1];
+ }
+ /*Length 19*/
+ else if(subparts.length == 19) {
+ capability = subparts[14].split("=")[1];
+ scontext = subparts[16].split("=")[1];
+ tcontext = subparts[17].split("=")[1];
+ tclass = subparts[18].split("=")[1];
+ }
+ /*Length 18*/
+ else if(subparts.length == 18) {
+ name = subparts[14].split("=")[1];
+ scontext = subparts[15].split("=")[1];
+ tcontext = subparts[16].split("=")[1];
+ tclass = subparts[17].split("=")[1];
+ }
+ /*Length 17*/
+ else if(subparts.length == 17) {
+ scontext = subparts[14].split("=")[1];
+ tcontext = subparts[15].split("=")[1];
+ tclass = subparts[16].split("=")[1];
+ }
+ else {
+ Log.e(logTag, "Could not parse \""+message+"\", length: "+subparts.length+" unknown!");
+ message = time = name = pid = command = null;
+ }
+ }
+
+}
diff --git a/src/com/android/seandroid_manager/AVCReader.java b/src/com/android/seandroid_manager/AVCReader.java
new file mode 100644
index 0000000..866f595
--- /dev/null
+++ b/src/com/android/seandroid_manager/AVCReader.java
@@ -0,0 +1,87 @@
+package com.android.seandroid_manager;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.util.Scanner;
+
+import android.util.Log;
+
+/**
+ *
+ * Reads the kernel message log and sends AVCDenied messages to
+ * the registered handler.
+ *
+ */
+public class AVCReader {
+
+ private String avcSearchTag = "avc";
+ private String logTag = "AVCReader";
+ private AVCCallback callback = null;
+ private static final AVCReader instance = new AVCReader();
+
+ private AVCReader() {}
+
+ /** Get the Singleton instance.
+ *
+ * @return
+ * the AVCReader singleton instance.
+ */
+ public static synchronized AVCReader getInstance() {
+ return instance;
+ }
+
+ /** Register a handler to handle avc denied messages.
+ *
+ * @param avcHandler
+ * The call back to handle AVC denied events.
+ *
+ * @param overide
+ * Whether or not to override an existing event handler, if true, then
+ * all calls will succeed and the existing handler will be replaced
+ * by avcHandler. On false, the call will succeed only if your registering the
+ * first handler.
+ *
+ * @return
+ * True if successful, False otherwise.
+ */
+ public synchronized boolean registerCallback(AVCCallback avcHandler, boolean overide) {
+
+ if((avcHandler != null) && (overide || (callback == null))) {
+ callback = avcHandler;
+ return true;
+ }
+ Log.e(logTag, "Could not set handler");
+ return false;
+ }
+
+ /** Reads from kernel logs, parses them and generates callbacks set by registerCallback
+ * for each avc denied message encountered.
+ *
+ */
+ public void parseLogs() {
+
+ int value;
+ byte logs[];
+ String line;
+ AVCDeniedMessage message;
+
+ value = KLogCtl.kLogCtl(10, null, 0);
+
+ logs = new byte[value];
+ value = KLogCtl.kLogCtl(3, logs, value);
+
+ Scanner stream = new Scanner(new ByteArrayInputStream(logs));
+
+ while(stream.hasNextLine()) {
+ line = stream.nextLine();
+ if(line.contains(avcSearchTag)) {
+
+ message = new AVCDeniedMessage(line);
+ callback.handleAVCEvent(message);
+ }
+ }
+ return;
+ }
+}
diff --git a/src/com/android/seandroid_manager/KLogCtl.java b/src/com/android/seandroid_manager/KLogCtl.java
new file mode 100644
index 0000000..03cb5f6
--- /dev/null
+++ b/src/com/android/seandroid_manager/KLogCtl.java
@@ -0,0 +1,40 @@
+package com.android.seandroid_manager;
+
+public class KLogCtl {
+
+ /** Reads from the kernel logs.
+ *
+ * See man klogctl
+ *
+ * @param type
+ * Determines the action to be taken by this function.
+ * Quoting from kernel/printk.c:
+ * Commands to sys_syslog:
+ *
+ * 0 -- Close the log. Currently a NOP.
+ * 1 -- Open the log. Currently a NOP.
+ * 2 -- Read from the log.
+ * 3 -- Read all messages remaining in the ring buffer.
+ * 4 -- Read and clear all messages remaining in the ring buffer
+ * 5 -- Clear ring buffer.
+ * 6 -- Disable printk to console
+ * 7 -- Enable printk to console
+ * 8 -- Set level of messages printed to console
+ * 9 -- Return number of unread characters in the log buffer
+ * 10 -- Return size of the log buffer
+ *
+ * @param buf
+ * Buffer to read the kernel log into.
+ *
+ * @param length
+ * The number of bytes to read.
+ *
+ * @return
+ * 0 on success or one of the stderror codes on error.
+ */
+ public static native int kLogCtl(int type, byte buf[], int length);
+
+ static {
+ System.loadLibrary("jni_klogctl");
+ }
+}
diff --git a/src/com/android/seandroid_manager/SEAndroidManager.java b/src/com/android/seandroid_manager/SEAndroidManager.java
index cf43f56..d0b0c52 100644
--- a/src/com/android/seandroid_manager/SEAndroidManager.java
+++ b/src/com/android/seandroid_manager/SEAndroidManager.java
@@ -11,6 +11,7 @@ import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen;
import android.provider.Settings;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -19,9 +20,11 @@ import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.TextView;
+import java.io.FileNotFoundException;
import java.util.List;
-public class SEAndroidManager extends PreferenceActivity {
+public class SEAndroidManager extends PreferenceActivity implements AVCCallback {
+
@Override
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource(R.xml.seandroid_manager_headers, target);
@@ -30,7 +33,6 @@ public class SEAndroidManager extends PreferenceActivity {
public static class SELinuxEnforcingFragment extends PreferenceFragment {
private static final String KEY_SELINUX_ENFORCING = "selinux_enforcing";
-
private CheckBoxPreference mSELinuxToggleEnforce;
@Override
@@ -121,4 +123,22 @@ public class SEAndroidManager extends PreferenceActivity {
setListAdapter(mAdapter);
}
}
+
+ @Override
+ public void handleAVCEvent(AVCDeniedMessage message) {
+ /*TODO: Handle message here and post to screen*/
+ Log.d("Message: ", message.toString());
+
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ /* TODO: Example code for reading the avc denied messages, need to remove when
+ * implementation is complete.
+ AVCReader reader = AVCReader.getInstance();
+ reader.registerCallback(this, false);
+ reader.parseLogs();
+ */
+ }
}
--
1.7.0.4
From 23e31e410f3815fde40ab72725c0d6bbda381c53 Mon Sep 17 00:00:00 2001
From: William Roberts <w.roberts@xxxxxxxxxxxxxxx>
Date: Mon, 26 Mar 2012 17:56:24 -0700
Subject: [PATCH 2/2] Working logger
---
res/layout/avc_denied_reader.xml | 40 +++++++++
res/values/strings.xml | 5 +
res/xml/seandroid_manager_headers.xml | 5 +
src/com/android/seandroid_manager/AVCCallback.java | 19 ++++
src/com/android/seandroid_manager/AVCReader.java | 75 +++++++----------
.../seandroid_manager/SEAndroidManager.java | 91 +++++++++++++++-----
6 files changed, 168 insertions(+), 67 deletions(-)
create mode 100644 res/layout/avc_denied_reader.xml
diff --git a/res/layout/avc_denied_reader.xml b/res/layout/avc_denied_reader.xml
new file mode 100644
index 0000000..5cecec7
--- /dev/null
+++ b/res/layout/avc_denied_reader.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/linearLayout1"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <RelativeLayout
+ android:id="@+id/linearLayout2"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:id="@+id/refreshButton"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_centerHorizontal="true"
+ android:layout_centerVertical="true"
+ android:layout_alignParentRight="@+id/linearLayout2"
+ android:text="@string/avc_denied_log_refresh_button_label"
+ android:layout_toRightOf="@+id/textView1" />
+
+ </RelativeLayout>
+
+
+ <ScrollView
+ android:id="@+id/avcLogScrollView"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <TextView
+ android:id="@+id/avcLogTextView"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/avc_denied_log_reload_msg" />
+
+ </ScrollView>
+
+
+ </LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f892438..7c4834a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -14,4 +14,9 @@
<string name="selinux_manage_booleans">SELinux Booleans</string>
<string name="selinux_manage_booleans_summary">Manage SELinux Booleans</string>
<string name="selinux_no_booleans">No Booleans</string>
+ <string name="avc_denied_log_fragment_title">AVC Denied Logs</string>
+ <string name="avc_denied_log_reload_msg">Press The "Refresh" Button to Update AVC Denied Messages</string>
+ <string name="avc_denied_log_refresh_button_label">Refresh</string>
+ <string name="avc_denied_log_refresh_text">Refresh AVC Logs</string>
</resources>
+
diff --git a/res/xml/seandroid_manager_headers.xml b/res/xml/seandroid_manager_headers.xml
index bd63280..12db791 100644
--- a/res/xml/seandroid_manager_headers.xml
+++ b/res/xml/seandroid_manager_headers.xml
@@ -12,4 +12,9 @@
android:title="@string/selinux_boolean_fragment_title">
</header>
+ <header
+ android:fragment="com.android.seandroid_manager.SEAndroidManager$AVCDeniedReaderFragment"
+ android:title="@string/avc_denied_log_fragment_title">
+ </header>
+
</preference-headers>
diff --git a/src/com/android/seandroid_manager/AVCCallback.java b/src/com/android/seandroid_manager/AVCCallback.java
index 34d8632..8da986e 100644
--- a/src/com/android/seandroid_manager/AVCCallback.java
+++ b/src/com/android/seandroid_manager/AVCCallback.java
@@ -1,7 +1,26 @@
package com.android.seandroid_manager;
+/**
+ * Used to handle events from parsing the kernel logs looking for AVC messages.
+ *
+ */
public interface AVCCallback {
+ /** Before parsing begins, this function is called.
+ *
+ */
+ public void onStart();
+
+ /** For each AVC denied message encountered, this callback is called.
+ *
+ * @param message
+ * The exact AVC denied message encountered while parsing.
+ */
public void handleAVCEvent(AVCDeniedMessage message);
+ /** This is called at the end of parsing, when no more messages are found.
+ *
+ */
+ public void onFinish();
+
}
diff --git a/src/com/android/seandroid_manager/AVCReader.java b/src/com/android/seandroid_manager/AVCReader.java
index 866f595..33ba378 100644
--- a/src/com/android/seandroid_manager/AVCReader.java
+++ b/src/com/android/seandroid_manager/AVCReader.java
@@ -1,12 +1,9 @@
package com.android.seandroid_manager;
import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.util.Scanner;
-import android.util.Log;
+import android.os.AsyncTask;
/**
*
@@ -14,53 +11,20 @@ import android.util.Log;
* the registered handler.
*
*/
-public class AVCReader {
+public class AVCReader extends AsyncTask<Void, AVCDeniedMessage, Void> {
private String avcSearchTag = "avc";
- private String logTag = "AVCReader";
private AVCCallback callback = null;
- private static final AVCReader instance = new AVCReader();
- private AVCReader() {}
-
- /** Get the Singleton instance.
- *
- * @return
- * the AVCReader singleton instance.
- */
- public static synchronized AVCReader getInstance() {
- return instance;
+ public AVCReader(AVCCallback avcHandler) {
+ callback = avcHandler;
}
- /** Register a handler to handle avc denied messages.
- *
- * @param avcHandler
- * The call back to handle AVC denied events.
- *
- * @param overide
- * Whether or not to override an existing event handler, if true, then
- * all calls will succeed and the existing handler will be replaced
- * by avcHandler. On false, the call will succeed only if your registering the
- * first handler.
- *
- * @return
- * True if successful, False otherwise.
- */
- public synchronized boolean registerCallback(AVCCallback avcHandler, boolean overide) {
-
- if((avcHandler != null) && (overide || (callback == null))) {
- callback = avcHandler;
- return true;
- }
- Log.e(logTag, "Could not set handler");
- return false;
- }
-
- /** Reads from kernel logs, parses them and generates callbacks set by registerCallback
+ /** Reads from kernel logs, parses them and calls the callbacks set by registerCallback
* for each avc denied message encountered.
*
*/
- public void parseLogs() {
+ private void parseLogs() {
int value;
byte logs[];
@@ -74,14 +38,37 @@ public class AVCReader {
Scanner stream = new Scanner(new ByteArrayInputStream(logs));
- while(stream.hasNextLine()) {
+ while(stream.hasNextLine() && !isCancelled()) {
line = stream.nextLine();
if(line.contains(avcSearchTag)) {
message = new AVCDeniedMessage(line);
- callback.handleAVCEvent(message);
+ publishProgress(message);
}
}
+
+ return;
+ }
+
+ @Override
+ protected void onPostExecute(Void result) {
+ callback.onFinish();
+ }
+
+ @Override
+ protected void onPreExecute() {
+ callback.onStart();
+ }
+
+ @Override
+ protected Void doInBackground(Void... params) {
+ parseLogs();
+ return null;
+ }
+
+ @Override
+ protected void onProgressUpdate(AVCDeniedMessage... message) {
+ callback.handleAVCEvent(message[0]);
return;
}
}
diff --git a/src/com/android/seandroid_manager/SEAndroidManager.java b/src/com/android/seandroid_manager/SEAndroidManager.java
index d0b0c52..4342bf6 100644
--- a/src/com/android/seandroid_manager/SEAndroidManager.java
+++ b/src/com/android/seandroid_manager/SEAndroidManager.java
@@ -1,6 +1,9 @@
package com.android.seandroid_manager;
+import android.app.Activity;
+import android.app.Fragment;
import android.app.ListFragment;
+import android.app.ProgressDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
@@ -10,26 +13,86 @@ import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen;
-import android.provider.Settings;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
+import android.widget.ScrollView;
import android.widget.TextView;
+import android.view.View.OnClickListener;
-import java.io.FileNotFoundException;
import java.util.List;
-public class SEAndroidManager extends PreferenceActivity implements AVCCallback {
+public class SEAndroidManager extends PreferenceActivity {
@Override
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource(R.xml.seandroid_manager_headers, target);
}
+ public static class AVCDeniedReaderFragment extends Fragment {
+
+ private TextView logs;
+ private ScrollView scrollView;
+ private ProgressDialog progressDialog;
+
+ private AVCCallback handleMessage = new AVCCallback() {
+
+ public void onStart() {
+ progressDialog.show();
+ }
+
+ public void handleAVCEvent(AVCDeniedMessage message) {
+ logs.append(message.getRawMessage()+"\n\n");
+ }
+
+ public void onFinish() {
+ scrollView.post(new Runnable() {
+ public void run() {
+ scrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ progressDialog.cancel();
+ }
+
+ };
+
+ private OnClickListener onAVCRefreshClick = new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ logs.setText(null);
+ AVCReader logReader = new AVCReader(handleMessage);
+ logReader.execute();
+ }
+
+ };
+
+ @Override
+ public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ View v = inflater.inflate(R.layout.avc_denied_reader, container, false);
+
+ Button b = (Button)v.findViewById(R.id.refreshButton);
+ b.setOnClickListener(onAVCRefreshClick);
+
+ logs = (TextView)v.findViewById(R.id.avcLogTextView);
+
+ scrollView = (ScrollView)v.findViewById(R.id.avcLogScrollView);
+
+ progressDialog = new ProgressDialog(getActivity());
+ progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
+ progressDialog.setMessage("Loading...");
+
+ return v;
+ }
+
+ }
+
public static class SELinuxEnforcingFragment extends PreferenceFragment {
private static final String KEY_SELINUX_ENFORCING = "selinux_enforcing";
@@ -38,8 +101,8 @@ public class SEAndroidManager extends PreferenceActivity implements AVCCallback
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
addPreferencesFromResource(R.xml.selinux_enforcing_fragment);
+
mSELinuxToggleEnforce = (CheckBoxPreference) getPreferenceScreen().findPreference(KEY_SELINUX_ENFORCING);
mSELinuxToggleEnforce.setChecked(SELinux.isSELinuxEnforced());
}
@@ -123,22 +186,4 @@ public class SEAndroidManager extends PreferenceActivity implements AVCCallback
setListAdapter(mAdapter);
}
}
-
- @Override
- public void handleAVCEvent(AVCDeniedMessage message) {
- /*TODO: Handle message here and post to screen*/
- Log.d("Message: ", message.toString());
-
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- /* TODO: Example code for reading the avc denied messages, need to remove when
- * implementation is complete.
- AVCReader reader = AVCReader.getInstance();
- reader.registerCallback(this, false);
- reader.parseLogs();
- */
- }
}
--
1.7.0.4
[Fedora Users] [Fedora Legacy] [Fedora Desktop] [Yosemite Photos] [Yosemite News] [Yosemite Campsites] [KDE Users] [Gnome Users]