OSDN Git Service

Progress towards FBE and adoptable storage.
[android-x86/system-vold.git] / CryptCommandListener.cpp
index 75c840f..779338f 100644 (file)
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <assert.h>
 #include <stdlib.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
@@ -49,6 +50,7 @@
 #include "ResponseCode.h"
 #include "cryptfs.h"
 #include "Ext4Crypt.h"
+#include "MetadataCrypt.h"
 #include "Utils.h"
 
 #define DUMP_ARGS 0
@@ -90,8 +92,8 @@ void CryptCommandListener::dumpArgs(int argc, char **argv, int argObscure) {
 void CryptCommandListener::dumpArgs(int /*argc*/, char ** /*argv*/, int /*argObscure*/) { }
 #endif
 
-int CryptCommandListener::sendGenericOkFail(SocketClient *cli, int cond) {
-    if (!cond) {
+int CryptCommandListener::sendGenericOkFailOnBool(SocketClient *cli, bool success) {
+    if (success) {
         return cli->sendMsg(ResponseCode::CommandOkay, "Command succeeded", false);
     } else {
         return cli->sendMsg(ResponseCode::OperationFailed, "Command failed", false);
@@ -145,22 +147,27 @@ static bool check_argc(SocketClient *cli, const std::string &subcommand, int arg
     return false;
 }
 
-static int do_enablecrypto(char** argv, int type, bool no_ui) {
+static int do_enablecrypto(char* arg2, char* arg4, int type, bool no_ui) {
     int rc;
     int tries;
     for (tries = 0; tries < 2; ++tries) {
         if (type == CRYPT_TYPE_DEFAULT) {
-            rc = cryptfs_enable_default(argv[2], no_ui);
+            rc = cryptfs_enable_default(arg2, no_ui);
         } else {
-            rc = cryptfs_enable(argv[2], type, argv[4], no_ui);
+            rc = cryptfs_enable(arg2, type, arg4, no_ui);
         }
 
         if (rc == 0) {
+            free(arg2);
+            free(arg4);
             return 0;
         } else if (tries == 0) {
             Process::killProcessesWithOpenFiles(DATA_MNT_POINT, SIGKILL);
         }
     }
+
+    free(arg2);
+    free(arg4);
     return -1;
 }
 
@@ -195,6 +202,15 @@ int CryptCommandListener::CryptfsCmd::runCommand(SocketClient *cli,
         dumpArgs(argc, argv, -1);
         rc = cryptfs_crypto_complete();
     } else if (subcommand == "enablecrypto") {
+        if (e4crypt_is_native()) {
+            if (argc != 5 || strcmp(argv[2], "inplace") || strcmp(argv[3], "default")
+                    || strcmp(argv[4], "noui")) {
+                cli->sendMsg(ResponseCode::CommandSyntaxError,
+                        "Usage with ext4crypt: cryptfs enablecrypto inplace default noui", false);
+                return 0;
+            }
+            return sendGenericOkFailOnBool(cli, e4crypt_enable_crypto());
+        }
         const char* syntax = "Usage: cryptfs enablecrypto <wipe|inplace> "
                              "default|password|pin|pattern [passwd] [noui]";
 
@@ -248,11 +264,13 @@ int CryptCommandListener::CryptfsCmd::runCommand(SocketClient *cli,
 
         // Spawn as thread so init can issue commands back to vold without
         // causing deadlock, usually as a result of prep_data_fs.
-        std::thread(&do_enablecrypto, argv, type, no_ui).detach();
+        char* arg2 = argc > 2 ? strdup(argv[2]) : NULL;
+        char* arg4 = argc > 4 ? strdup(argv[4]) : NULL;
+        std::thread(&do_enablecrypto, arg2, arg4, type, no_ui).detach();
     } else if (subcommand == "enablefilecrypto") {
         if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
         dumpArgs(argc, argv, -1);
-        rc = cryptfs_enable_file();
+        rc = e4crypt_initialize_global_de();
     } else if (subcommand == "changepw") {
         const char* syntax = "Usage: cryptfs changepw "
                              "default|password|pin|pattern [newpasswd]";
@@ -310,6 +328,9 @@ int CryptCommandListener::CryptfsCmd::runCommand(SocketClient *cli,
         SLOGD("cryptfs mountdefaultencrypted");
         dumpArgs(argc, argv, -1);
 
+        if (e4crypt_is_native()) {
+            return sendGenericOkFailOnBool(cli, e4crypt_mount_metadata_encrypted());
+        }
         // Spawn as thread so init can issue commands back to vold without
         // causing deadlock, usually as a result of prep_data_fs.
         std::thread(&cryptfs_mount_default_encrypted).detach();
@@ -367,35 +388,49 @@ int CryptCommandListener::CryptfsCmd::runCommand(SocketClient *cli,
 
     } else if (subcommand == "init_user0") {
         if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
-        return sendGenericOkFail(cli, e4crypt_init_user0());
+        return sendGenericOkFailOnBool(cli, e4crypt_init_user0());
 
     } else if (subcommand == "create_user_key") {
         if (!check_argc(cli, subcommand, argc, 5, "<user> <serial> <ephemeral>")) return 0;
-        return sendGenericOkFail(cli,
-                                 e4crypt_vold_create_user_key(atoi(argv[2]),
-                                                              atoi(argv[3]),
-                                                              atoi(argv[4]) != 0));
+        return sendGenericOkFailOnBool(cli, e4crypt_vold_create_user_key(
+            atoi(argv[2]), atoi(argv[3]), atoi(argv[4]) != 0));
 
     } else if (subcommand == "destroy_user_key") {
         if (!check_argc(cli, subcommand, argc, 3, "<user>")) return 0;
-        return sendGenericOkFail(cli, e4crypt_destroy_user_key(atoi(argv[2])));
+        return sendGenericOkFailOnBool(cli, e4crypt_destroy_user_key(atoi(argv[2])));
+
+    } else if (subcommand == "add_user_key_auth") {
+        if (!check_argc(cli, subcommand, argc, 6, "<user> <serial> <token> <secret>")) return 0;
+        return sendGenericOkFailOnBool(cli, e4crypt_add_user_key_auth(
+            atoi(argv[2]), atoi(argv[3]), argv[4], argv[5]));
+
+    } else if (subcommand == "fixate_newest_user_key_auth") {
+        if (!check_argc(cli, subcommand, argc, 3, "<user>")) return 0;
+        return sendGenericOkFailOnBool(cli, e4crypt_fixate_newest_user_key_auth(atoi(argv[2])));
 
     } else if (subcommand == "unlock_user_key") {
-        if (!check_argc(cli, subcommand, argc, 5, "<user> <serial> <token>")) return 0;
-        return sendGenericOkFail(cli, e4crypt_unlock_user_key(
-            atoi(argv[2]), atoi(argv[3]), parseNull(argv[4])));
+        if (!check_argc(cli, subcommand, argc, 6, "<user> <serial> <token> <secret>")) return 0;
+        return sendGenericOkFailOnBool(cli, e4crypt_unlock_user_key(
+            atoi(argv[2]), atoi(argv[3]), argv[4], argv[5]));
 
     } else if (subcommand == "lock_user_key") {
         if (!check_argc(cli, subcommand, argc, 3, "<user>")) return 0;
-        return sendGenericOkFail(cli, e4crypt_lock_user_key(atoi(argv[2])));
+        return sendGenericOkFailOnBool(cli, e4crypt_lock_user_key(atoi(argv[2])));
 
     } else if (subcommand == "prepare_user_storage") {
         if (!check_argc(cli, subcommand, argc, 6, "<uuid> <user> <serial> <flags>")) return 0;
-        return sendGenericOkFail(cli,
-                                 e4crypt_prepare_user_storage(parseNull(argv[2]),
-                                                              atoi(argv[3]),
-                                                              atoi(argv[4]),
-                                                              atoi(argv[5])));
+        return sendGenericOkFailOnBool(cli, e4crypt_prepare_user_storage(
+            parseNull(argv[2]), atoi(argv[3]), atoi(argv[4]), atoi(argv[5])));
+
+    } else if (subcommand == "destroy_user_storage") {
+        if (!check_argc(cli, subcommand, argc, 5, "<uuid> <user> <flags>")) return 0;
+        return sendGenericOkFailOnBool(cli,
+                e4crypt_destroy_user_storage(parseNull(argv[2]), atoi(argv[3]), atoi(argv[4])));
+
+    } else if (subcommand == "secdiscard") {
+        if (!check_argc(cli, subcommand, argc, 3, "<path>")) return 0;
+        return sendGenericOkFailOnBool(cli,
+                e4crypt_secdiscard(parseNull(argv[2])));
 
     } else {
         dumpArgs(argc, argv, -1);