OSDN Git Service

assign user before use
[android-x86/external-koush-Superuser.git] / Superuser / jni / su / activity.c
index c48bf01..a3ef9c7 100644 (file)
 
 #include "su.h"
 
+/* intent actions */
+#define ACTION_REQUEST "start", "-n", REQUESTOR "/" REQUESTOR_PREFIX ".RequestActivity"
+#define ACTION_NOTIFY "start", "-n", REQUESTOR "/" REQUESTOR_PREFIX ".NotifyActivity"
+#define ACTION_RESULT "broadcast", "-n", REQUESTOR "/" REQUESTOR_PREFIX ".SuReceiver"
+
+#define AM_PATH "/system/bin/app_process", "/system/bin", "com.android.commands.am.Am"
+
 // TODO: leverage this with exec_log?
-static int silent_run(char* command) {
-    char *args[] = { "sh", "-c", command, NULL, };
+int silent_run(char* const args[]) {
     set_identity(0);
     pid_t pid;
     pid = fork();
@@ -45,7 +51,8 @@ static int silent_run(char* command) {
     int null = open("/dev/null", O_WRONLY | O_CLOEXEC);
     dup2(null, 1);
     dup2(null, 2);
-    execv(_PATH_BSHELL, args);
+    setenv("CLASSPATH", "/system/framework/am.jar", 1);
+    execv(args[0], args);
     PLOGE("exec am");
     _exit(EXIT_FAILURE);
     return -1;
@@ -58,39 +65,97 @@ int get_owner_login_user_args(struct su_context *ctx, char* user, int user_len)
         if (0 != ctx->user.android_user_id) {
             needs_owner_login_prompt = 1;
         }
-        snprintf(user, user_len, "--user 0");
+        snprintf(user, user_len, "0");
     }
     else if (ctx->user.multiuser_mode == MULTIUSER_MODE_USER) {
-        snprintf(user, user_len, "--user %d", ctx->user.android_user_id);
+        snprintf(user, user_len, "%d", ctx->user.android_user_id);
     }
     else if (ctx->user.multiuser_mode == MULTIUSER_MODE_NONE) {
-        snprintf(user, user_len, "");
+        user[0] = '\0';
     }
     else {
-        snprintf(user, user_len, "--user 0");
+        snprintf(user, user_len, "0");
     }
     
     return needs_owner_login_prompt;
 }
 
 int send_result(struct su_context *ctx, policy_t policy) {
+    char binary_version[256];
+    sprintf(binary_version, "%d", VERSION_CODE);
+
+    char uid[256];
+    sprintf(uid, "%d", ctx->from.uid);
+
+    char desired_uid[256];
+    sprintf(desired_uid, "%d", ctx->to.uid);
+
     char user[64];
     get_owner_login_user_args(ctx, user, sizeof(user));
-    
+
     if (0 != ctx->user.android_user_id) {
-        char user_result_command[ARG_MAX];
-        snprintf(user_result_command, sizeof(user_result_command), "exec /system/bin/am " ACTION_RESULT " --ei binary_version %d --es from_name '%s' --es desired_name '%s' --ei uid %d --ei desired_uid %d --es command '%s' --es action %s --user %d",
-            VERSION_CODE,
-            ctx->from.name, ctx->to.name,
-            ctx->from.uid, ctx->to.uid, get_command(&ctx->to), policy == ALLOW ? "allow" : "deny", ctx->user.android_user_id);
+        char android_user_id[256];
+        sprintf(android_user_id, "%d", ctx->user.android_user_id);
+
+        char *user_result_command[] = {
+            AM_PATH,
+            ACTION_RESULT,
+            "--ei",
+            "binary_version",
+            binary_version,
+            "--es",
+            "from_name",
+            ctx->from.name,
+            "--es",
+            "desired_name",
+            ctx->to.name,
+            "--ei",
+            "uid",
+            uid,
+            "--ei",
+            "desired_uid",
+            desired_uid,
+            "--es",
+            "command",
+            get_command(&ctx->to),
+            "--es",
+            "action",
+            policy == ALLOW ? "allow" : "deny",
+            user[0] ? "--user" : NULL,
+            android_user_id,
+            NULL
+        };
         silent_run(user_result_command);
     }
 
-    char result_command[ARG_MAX];
-    snprintf(result_command, sizeof(result_command), "exec /system/bin/am " ACTION_RESULT " --ei binary_version %d --es from_name '%s' --es desired_name '%s' --ei uid %d --ei desired_uid %d --es command '%s' --es action %s %s",
-        VERSION_CODE,
-        ctx->from.name, ctx->to.name,
-        ctx->from.uid, ctx->to.uid, get_command(&ctx->to), policy == ALLOW ? "allow" : "deny", user);
+    char *result_command[] = {
+        AM_PATH,
+        ACTION_RESULT,
+        "--ei",
+        "binary_version",
+        binary_version,
+        "--es",
+        "from_name",
+        ctx->from.name,
+        "--es",
+        "desired_name",
+        ctx->to.name,
+        "--ei",
+        "uid",
+        uid,
+        "--ei",
+        "desired_uid",
+        desired_uid,
+        "--es",
+        "command",
+        get_command(&ctx->to),
+        "--es",
+        "action",
+        policy == ALLOW ? "allow" : "deny",
+        user[0] ? "--user" : NULL,
+        user,
+        NULL
+    };
     return silent_run(result_command);
 }
 
@@ -104,13 +169,23 @@ int send_request(struct su_context *ctx) {
 
     int ret;
     if (needs_owner_login_prompt) {
-        // in multiuser mode, the owner gets the su prompt
-        char notify_command[ARG_MAX];
+        char uid[256];
+        sprintf(uid, "%d", ctx->from.uid);
 
-        // start the activity that confirms the request
-        snprintf(notify_command, sizeof(notify_command),
-            "exec /system/bin/am " ACTION_NOTIFY " --ei caller_uid %d --user %d",
-            ctx->from.uid, ctx->user.android_user_id);
+        char android_user_id[256];
+        sprintf(android_user_id, "%d", ctx->user.android_user_id);
+
+        // in multiuser mode, the owner gets the su prompt
+        char *notify_command[] = {
+            AM_PATH,
+            ACTION_NOTIFY,
+            "--ei",
+            "caller_uid",
+            uid,
+            "--user",
+            android_user_id,
+            NULL
+        };
 
         int ret = silent_run(notify_command);
         if (ret) {
@@ -118,12 +193,16 @@ int send_request(struct su_context *ctx) {
         }
     }
 
-    char request_command[ARG_MAX];
-
-    // start the activity that confirms the request
-    snprintf(request_command, sizeof(request_command),
-        "exec /system/bin/am " ACTION_REQUEST " --es socket '%s' %s",
-        ctx->sock_path, user);
+    char *request_command[] = {
+        AM_PATH,
+        ACTION_REQUEST,
+        "--es",
+        "socket",
+        ctx->sock_path,
+        user[0] ? "--user" : NULL,
+        user,
+        NULL
+    };
 
     return silent_run(request_command);
 }