dmcrypt feature 67/70967/10
authorjongmyeongko <jongmyeong.ko@samsung.com>
Mon, 23 May 2016 11:40:37 +0000 (20:40 +0900)
committerjongmyeongko <jongmyeong.ko@samsung.com>
Fri, 24 Jun 2016 09:58:28 +0000 (18:58 +0900)
Change-Id: I746e2ca60d4a8a73302f2d123381f6f08c3de32f
Signed-off-by: jongmyeongko <jongmyeong.ko@samsung.com>
CMakeLists.txt
inc/app2ext_interface.h
packaging/app2sd.spec
plugin/app2sd/CMakeLists.txt
plugin/app2sd/inc/app2sd_internals.h
plugin/app2sd/src/app2sd_interface.c
plugin/app2sd/src/app2sd_internals.c
plugin/app2sd/src/app2sd_internals_utils.c
test/CMakeLists.txt
test/src/test_app2ext.c

index 6731fb7..80df069 100644 (file)
@@ -39,6 +39,7 @@ SET(libapp2ext_LDFLAGS " -L${LIB_INSTALL_DIR} -module -avoid-version -ldl ")
 SET(libapp2ext_CFLAGS  " ${CFLAGS} -fPIC ")
 
 ADD_DEFINITIONS("-DLIBPREFIX=\"${LIB_INSTALL_DIR}\"")
+ADD_DEFINITIONS("-D_APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION")
 
 ADD_LIBRARY(${APP2EXT} SHARED ${libapp2ext_SOURCES})
 SET_TARGET_PROPERTIES(${APP2EXT} PROPERTIES SOVERSION ${VERSION_MAJOR})
index e145191..8811b8d 100644 (file)
@@ -155,7 +155,15 @@ typedef enum app2ext_error_t {
        APP2EXT_ERROR_MEMORY_ALLOC_FAILED,
        APP2EXT_ERROR_OPERATION_NOT_PERMITTED,
        APP2EXT_ERROR_SAME_LOOPBACK_DEVICE_EXISTS,
-       APP2EXT_ERROR_PKGMGR_ERROR
+       APP2EXT_ERROR_PKGMGR_ERROR,
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+       APP2EXT_ERROR_SETUP_DMCRYPT_DEVICE,
+       APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE,
+       APP2EXT_ERROR_CLOSE_DMCRYPT_DEVICE,
+       APP2EXT_ERROR_FIND_ASSOCIATED_DMCRYPT_DEVICE_NODE,
+       APP2EXT_ERROR_DMCRYPT_DEVICE_UNAVAILABLE,
+#endif
+       APP2EXT_ERROR_ENUM_MAX
 } app2ext_error;
 
 /**
index d6ff491..7e97826 100644 (file)
@@ -15,6 +15,7 @@ BuildRequires:  pkgconfig(minizip)
 BuildRequires:  pkgconfig(libtzplatform-config)
 BuildRequires:  pkgconfig(gio-2.0)
 BuildRequires:  pkgconfig(glib-2.0)
+BuildRequires:  cryptsetup
 BuildRequires:  cmake
 
 %description
index 1545c32..0177008 100644 (file)
@@ -33,6 +33,8 @@ SET(libapp2sd_SOURCES
 SET(libapp2sd_LDFLAGS " -L${LIB_INSTALL_DIR} -lcrypto -module -avoid-version ")
 SET(libapp2sd_CFLAGS  " ${CFLAGS} -fPIC ")
 
+ADD_DEFINITIONS("-D_APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION")
+
 ADD_LIBRARY(${APP2SD} SHARED ${libapp2sd_SOURCES})
 SET_TARGET_PROPERTIES(${APP2SD} PROPERTIES SOVERSION ${VERSION_MAJOR})
 SET_TARGET_PROPERTIES(${APP2SD} PROPERTIES VERSION ${VERSION})
index 66bdfd6..2b9c2a3 100644 (file)
@@ -49,6 +49,7 @@
 #include <malloc.h>
 #include <math.h>
 #include <errno.h>
+#include <stdbool.h>
 
 #include "app2sd_interface.h"
 
@@ -173,4 +174,20 @@ int _app2sd_get_info_from_db(const char *filename, char **pkgid, uid_t *uid);
 int _app2sd_force_clean(const char *pkgid, const char *application_path,
                const char *loopback_device, uid_t uid);
 
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+/*This function setup dmcrypt header in the app2sd file */
+int _app2sd_dmcrypt_setup_device(const char *pkgid,
+               const char *loopback_device, bool is_dup, uid_t uid);
+
+/*This function maps the app2sd file with a dmcrypt device node */
+int _app2sd_dmcrypt_open_device(const char *pkgid, const char *loopback_device,
+               bool is_dup, uid_t uid, char **dev_node);
+
+/*This function remove dmcrypt device node */
+int _app2sd_dmcrypt_close_device(const char *pkgid, uid_t uid);
+
+/*This function find associated dmcrypt device node */
+char *_app2sd_find_associated_dmcrypt_device_node(const char *pkgid, uid_t uid);
+#endif
+
 #endif
index 6f2f53d..c08fdc1 100644 (file)
@@ -47,7 +47,9 @@ int app2sd_usr_pre_app_install(const char *pkgid, GList *dir_list, int size, uid
        int ret = 0;
        int free_mmc_mem = 0;
        char *device_node = NULL;
+#if !defined(_APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION)
        char *devi = NULL;
+#endif
        char *result = NULL;
        char application_path[FILENAME_MAX] = { 0, };
        char loopback_device[FILENAME_MAX] = { 0, };
@@ -123,6 +125,20 @@ int app2sd_usr_pre_app_install(const char *pkgid, GList *dir_list, int size, uid
        ret = _app2sd_create_loopback_device(pkgid, loopback_device,
                (reqd_disk_size + PKG_BUF_SIZE));
 
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+       ret = _app2sd_dmcrypt_setup_device(pkgid, loopback_device, false, uid);
+       if (ret) {
+               _E("dmcrypt setup device error");
+               return APP2EXT_ERROR_SETUP_DMCRYPT_DEVICE;
+       }
+
+       ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
+               false, uid, &device_node);
+       if (ret) {
+               _E("dmcrypt open device error");
+               return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
+       }
+#else
        /* perform loopback encryption setup */
        device_node = _app2sd_do_loopback_encryption_setup(pkgid,
                loopback_device, uid);
@@ -141,6 +157,7 @@ int app2sd_usr_pre_app_install(const char *pkgid, GList *dir_list, int size, uid
                ret = APP2EXT_ERROR_DO_LOSETUP;
                goto FINISH_OFF;
        }
+#endif
 
        /* format the loopback file system */
        ret = _app2sd_create_file_system(device_node);
@@ -168,12 +185,19 @@ int app2sd_usr_pre_app_install(const char *pkgid, GList *dir_list, int size, uid
 
 FINISH_OFF:
        if (device_node) {
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+       ret = _app2sd_dmcrypt_close_device(pkgid, uid);
+       if (ret)
+               _E("close dmcrypt device error(%d)", ret);
+       _app2sd_delete_loopback_device(loopback_device);
+#else
                result = _app2sd_detach_loop_device(device_node);
                if (result) {
                        free(result);
                        result = NULL;
                }
                _app2sd_delete_loopback_device(loopback_device);
+#endif
        }
 
 END:
@@ -182,10 +206,12 @@ END:
                device_node = NULL;
        }
 
+#if !defined(_APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION)
        if (devi) {
                free(devi);
                devi = NULL;
        }
+#endif
 
        return ret;
 }
@@ -235,9 +261,16 @@ int app2sd_usr_post_app_install(const char *pkgid,
        free(encoded_id);
 
        /* get the associated device node for SD card applicationer */
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+       device_name =
+               _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
+       if (!device_name)
+               return APP2EXT_ERROR_FIND_ASSOCIATED_DMCRYPT_DEVICE_NODE;
+#else
        device_name = _app2sd_find_associated_device_node(loopback_device);
        if (NULL == device_name)
                return APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
+#endif
 
        ret = _app2sd_unmount_app_content(application_path);
        if (ret) {
@@ -249,6 +282,17 @@ int app2sd_usr_post_app_install(const char *pkgid,
                return APP2EXT_ERROR_UNMOUNT;
        }
 
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+       ret = _app2sd_dmcrypt_close_device(pkgid, uid);
+       if (ret) {
+               if (device_name) {
+                       free(device_name);
+                       device_name = NULL;
+               }
+               _E("close dmcrypt device error(%d)", ret);
+               return ret;
+       }
+#else
        ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
        if (ret) {
                if (device_name) {
@@ -259,6 +303,7 @@ int app2sd_usr_post_app_install(const char *pkgid,
                        " for the application");
                return APP2EXT_ERROR_UNMOUNT;
        }
+#endif
 
        if (device_name) {
                free(device_name);
@@ -306,7 +351,9 @@ int app2sd_usr_on_demand_setup_init(const char *pkgid, uid_t uid)
        char loopback_device[FILENAME_MAX] = { 0, };
        char *encoded_id = NULL;
        char *device_node = NULL;
+#if !defined(_APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION)
        char *result = NULL;
+#endif
        FILE *fp = NULL;
 
        /* validate the function parameter recieved */
@@ -349,6 +396,21 @@ int app2sd_usr_on_demand_setup_init(const char *pkgid, uid_t uid)
        }
        fclose(fp);
 
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+       device_node =
+               _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
+       if (device_node) {
+               _E("device_node(%s_%d) already associated", pkgid, uid);
+               return APP2EXT_ERROR_ALREADY_MOUNTED;
+       }
+
+       ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
+               false, uid, &device_node);
+       if (ret) {
+               _E("dmcrypt open device error(%d)", ret);
+               return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
+       }
+#else
        result = (char *)_app2sd_find_associated_device(loopback_device);
        /* process the string */
        if ((result != NULL) && strstr(result, "/dev") != NULL) {
@@ -365,6 +427,7 @@ int app2sd_usr_on_demand_setup_init(const char *pkgid, uid_t uid)
                _E("loopback encryption setup failed");
                return APP2EXT_ERROR_DO_LOSETUP;
        }
+#endif
 
        /* do mounting */
        ret = _app2sd_mount_app_content(application_path, pkgid,
@@ -440,11 +503,17 @@ int app2sd_usr_on_demand_setup_exit(const char *pkgid, uid_t uid)
                return APP2EXT_ERROR_UNMOUNT;
        }
 
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+       ret = _app2sd_dmcrypt_close_device(pkgid, uid);
+       if (ret)
+               _E("close dmcrypt device error(%d)", ret);
+#else
        ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
        if (ret) {
                _E("unable to remove loopback setup");
                return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
        }
+#endif
 
        return ret;
 }
@@ -502,9 +571,22 @@ int app2sd_usr_pre_app_uninstall(const char *pkgid, uid_t uid)
        fclose(fp);
 
        /* get the associated device node for SD card applicationer */
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+       device_node =
+               _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
+#else
        device_node = _app2sd_find_associated_device_node(loopback_device);
+#endif
        if (NULL == device_node) {
                /* do loopback setup */
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+               ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
+                       false, uid, &device_node);
+               if (ret) {
+                       _E("dmcrypt open device error(%d)", ret);
+                       return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
+               }
+#else
                device_node = _app2sd_do_loopback_encryption_setup(pkgid,
                        loopback_device, uid);
                if (device_node == NULL) {
@@ -512,6 +594,7 @@ int app2sd_usr_pre_app_uninstall(const char *pkgid, uid_t uid)
                        ret = APP2EXT_ERROR_DO_LOSETUP;
                        goto END;
                }
+#endif
                /* do mounting */
                ret = _app2sd_mount_app_content(application_path, pkgid,
                        device_node, MOUNT_TYPE_RW, NULL,
@@ -600,6 +683,13 @@ int app2sd_usr_post_app_uninstall(const char *pkgid, uid_t uid)
                goto END;
        }
        /* detach the loopback encryption setup for the application */
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+       ret = _app2sd_dmcrypt_close_device(pkgid, uid);
+       if (ret) {
+               _E("close dmcrypt device error(%d)", ret);
+               goto END;
+       }
+#else
        ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
        if (ret) {
                _E("unable to Detach the loopback encryption setup" \
@@ -607,6 +697,7 @@ int app2sd_usr_post_app_uninstall(const char *pkgid, uid_t uid)
                ret = APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
                goto END;
        }
+#endif
 
        /* delete the loopback device from the SD card */
        ret = _app2sd_delete_loopback_device(loopback_device);
@@ -863,15 +954,29 @@ int app2sd_usr_pre_app_upgrade(const char *pkgid, GList *dir_list,
        }
 
        /* get the associated device node for SD card applicationer */
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+       device_node =
+               _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
+#else
        device_node = _app2sd_find_associated_device_node(loopback_device);
+#endif
        if (NULL == device_node) {
                /* do loopback setup */
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+               ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
+                       false, uid, &device_node);
+               if (ret) {
+                       _E("dmcrypt open device error");
+                       return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
+               }
+#else
                device_node = _app2sd_do_loopback_encryption_setup(pkgid,
                        loopback_device, uid);
                if (device_node == NULL) {
                        _E("loopback encryption setup failed");
                        return APP2EXT_ERROR_DO_LOSETUP;
                }
+#endif
 
                /* do mounting */
                ret = _app2sd_mount_app_content(application_path, pkgid,
@@ -950,9 +1055,19 @@ int app2sd_usr_post_app_upgrade(const char *pkgid,
        free(encoded_id);
 
        /* get the associated device node for SD card applicationer */
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+       device_name =
+               _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
+       if (!device_name) {
+               _E("could not find associated dmcrypt device node" \
+                       " (%s_%d)", pkgid, uid);
+               return APP2EXT_ERROR_FIND_ASSOCIATED_DMCRYPT_DEVICE_NODE;
+       }
+#else
        device_name = _app2sd_find_associated_device_node(loopback_device);
        if (NULL == device_name)
                return APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
+#endif
 
        ret = _app2sd_unmount_app_content(application_path);
        if (ret) {
@@ -964,6 +1079,17 @@ int app2sd_usr_post_app_upgrade(const char *pkgid,
                return APP2EXT_ERROR_UNMOUNT;
        }
 
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+       ret = _app2sd_dmcrypt_close_device(pkgid, uid);
+       if (ret) {
+               if (device_name) {
+                       free(device_name);
+                       device_name = NULL;
+               }
+               _E("close dmcrypt device error(%d)", ret);
+               return APP2EXT_ERROR_CLOSE_DMCRYPT_DEVICE;
+       }
+#else
        ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
        if (ret) {
                if (device_name) {
@@ -974,6 +1100,7 @@ int app2sd_usr_post_app_upgrade(const char *pkgid,
                        "setup for the application");
                return APP2EXT_ERROR_UNMOUNT;
        }
+#endif
 
        if (device_name) {
                free(device_name);
index 686073a..92eb81a 100644 (file)
 
 #include "app2sd_internals.h"
 
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+#define DMCRYPT_ITER_TIME      50
+#define DMCRYPT_KEY_LEN                128
+#endif
+
 static int _app2sd_make_directory(const char *path, uid_t uid)
 {
        int ret = 0;
@@ -350,6 +355,214 @@ int _app2sd_remove_all_loopback_encryption_setups(const char *loopback_device)
        return ret;
 }
 
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+int _app2sd_dmcrypt_setup_device(const char *pkgid,
+               const char *loopback_device, bool is_dup, uid_t uid)
+{
+       int ret = APP2EXT_SUCCESS;
+       char *passwd = NULL;
+       char dmcrypt_setup_cmd[BUF_SIZE] = { 0, };
+       char err_buf[BUF_SIZE] = { 0, };
+
+       if (pkgid == NULL || loopback_device == NULL) {
+               _E("invalid argument");
+               return APP2EXT_ERROR_INVALID_ARGUMENTS;
+       }
+
+       /* get password for dmcrypt encryption */
+       ret = _app2sd_initialize_db();
+       if (ret) {
+               _E("app2sd db initialize failed");
+               return APP2EXT_ERROR_DB_INITIALIZE;
+       }
+
+       passwd = _app2sd_get_password_from_db(pkgid, uid);
+       if (passwd == NULL) {
+               if (is_dup) {
+                       _E("no password found for (%s)", pkgid);
+                       return APP2EXT_ERROR_SQLITE_REGISTRY;
+               }
+               passwd = (char *)_app2sd_generate_password(pkgid);
+               if (NULL == passwd) {
+                       _E("unable to generate password\n");
+                       return APP2EXT_ERROR_PASSWD_GENERATION;
+               } else {
+                       if ((ret = _app2sd_set_info_in_db(pkgid, passwd,
+                               loopback_device, uid)) < 0) {
+                               _E("unable to save password");
+                               free(passwd);
+                               passwd = NULL;
+                               return APP2EXT_ERROR_SQLITE_REGISTRY;
+                       }
+               }
+       }
+
+       snprintf(dmcrypt_setup_cmd, BUF_SIZE, "echo '%s' | cryptsetup -q -i %d " \
+               "-c aes-cbc-lmk -s %d --align-payload=8 luksFormat %s",
+               passwd, DMCRYPT_ITER_TIME, DMCRYPT_KEY_LEN, loopback_device);
+
+       ret = system(dmcrypt_setup_cmd);
+       if (ret) {
+               if (strerror_r(errno, err_buf, sizeof(err_buf)))
+                       _E("Error setting up dmcrypt on app2sd file, " \
+                               "error(%s), ret(%d)", err_buf, ret);
+               if (passwd) {
+                       free(passwd);
+                       passwd = NULL;
+               }
+               return APP2EXT_ERROR_SETUP_DMCRYPT_DEVICE;
+       }
+
+       if (passwd) {
+               free(passwd);
+               passwd = NULL;
+       }
+
+       return ret;
+}
+
+int _app2sd_dmcrypt_open_device(const char *pkgid, const char *loopback_device,
+               bool is_dup, uid_t uid, char **dev_node)
+{
+       int ret = APP2EXT_SUCCESS;
+       char *passwd = NULL;
+       char dmcrypt_open_cmd[BUF_SIZE] = { 0, };
+       char dev_name[BUF_SIZE] = { 0, };
+       char buf[BUF_SIZE] = { 0, };
+       int len = 0;
+
+       if (pkgid == NULL || loopback_device == NULL) {
+               _E("invalid argument");
+               return APP2EXT_ERROR_INVALID_ARGUMENTS;
+       }
+
+       if (is_dup)
+               snprintf(dev_name, BUF_SIZE, "%s.new_%d", pkgid, uid);
+       else
+               snprintf(dev_name, BUF_SIZE, "%s_%d", pkgid, uid);
+
+       /* get password for dmcrypt encryption */
+       ret = _app2sd_initialize_db();
+       if (ret) {
+               _E("app2sd db initialize failed");
+               return APP2EXT_ERROR_DB_INITIALIZE;
+       }
+       if ((passwd = _app2sd_get_password_from_db(pkgid, uid)) == NULL) {
+               _E("no password found for [%s]", pkgid);
+               return APP2EXT_ERROR_SQLITE_REGISTRY;
+       }
+
+       snprintf(dmcrypt_open_cmd, BUF_SIZE, "echo '%s' | cryptsetup -q luksOpen %s %s",
+               passwd, loopback_device, dev_name);
+
+       ret = system(dmcrypt_open_cmd);
+       if (ret) {
+               if (strerror_r(errno, buf, sizeof(buf)))
+                       _E("error opening dmcrypt device, error: [%s]", buf);
+               return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
+       }
+
+       snprintf(buf, BUF_SIZE, "/dev/mapper/%s", dev_name);
+       len = strlen(buf);
+       *dev_node = (char *)calloc(len + 1, sizeof(char));
+       if (*dev_node == NULL) {
+               _E("memory alloc failed");
+               return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
+       }
+       snprintf(*dev_node, len + 1, "%s", buf);
+
+       return ret;
+}
+
+int _app2sd_dmcrypt_close_device(const char *pkgid, uid_t uid)
+{
+       int ret = APP2EXT_SUCCESS;
+       char dev_node[BUF_SIZE] = { '\0' };
+       char dmcrypt_close_cmd[BUF_SIZE] = { '\0' };
+       char err_buf[BUF_SIZE] = { '\0' };
+       char *t_dev_node = NULL;
+
+       if (pkgid == NULL) {
+               _E("invalid argument\n");
+               return APP2EXT_ERROR_INVALID_ARGUMENTS;
+       }
+
+       t_dev_node = _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
+       if (!t_dev_node) {
+               _E("no associated device node(%s_%d) found", pkgid, uid);
+               return APP2EXT_ERROR_DMCRYPT_DEVICE_UNAVAILABLE;
+       }
+
+       free(t_dev_node);
+       t_dev_node = NULL;
+
+       snprintf(dev_node, BUF_SIZE, "/dev/mapper/%s_%d", pkgid, uid);
+       snprintf(dmcrypt_close_cmd, BUF_SIZE, "cryptsetup -q luksClose %s", dev_node);
+       ret = system(dmcrypt_close_cmd);
+       if (ret) {
+               if (strerror_r(errno, err_buf, sizeof(err_buf)))
+                       _E("error closing dmcrypt on app2sd file,"\
+                               " error: [%s]", err_buf);
+               return APP2EXT_ERROR_CLOSE_DMCRYPT_DEVICE;
+       }
+
+       return ret;
+}
+
+char *_app2sd_find_associated_dmcrypt_device_node(const char *pkgid, uid_t uid)
+{
+       char *dev_node = NULL;
+       char buf[BUF_SIZE] = { 0, };
+       int len = 0;
+
+       snprintf(buf, BUF_SIZE, "/dev/mapper/%s_%d", pkgid, uid);
+       len = strlen(buf);
+       dev_node = (char *)calloc(len + 1, sizeof(char));
+       if (dev_node == NULL) {
+               _E("memory alloc failed");
+               return NULL;
+       }
+       snprintf(dev_node, len + 1, "%s", buf);
+
+       if (access(dev_node, F_OK) == 0) {
+               _D("device_node: (%s)", dev_node);
+               return dev_node;
+       }
+
+       free(dev_node);
+       dev_node = NULL;
+
+       return NULL;
+}
+
+char *_app2sd_dmcrypt_duplicate_encryption_setup(const char *pkgid,
+               const char *temp_loopback_device, uid_t uid)
+{
+       int ret = APP2EXT_SUCCESS;
+       char *device_node = NULL;
+
+       if (pkgid == NULL || temp_loopback_device == NULL) {
+               _E("invalid argument\n");
+               return NULL;
+       }
+
+       ret = _app2sd_dmcrypt_setup_device(pkgid, temp_loopback_device, true, uid);
+       if (ret) {
+               _E("dmcrypt setup device error(%d)", ret);
+               return NULL;
+       }
+
+       ret = _app2sd_dmcrypt_open_device(pkgid, temp_loopback_device, true,
+               uid, &device_node);
+       if (ret) {
+               _E("dmcrypt open device error");
+               return NULL;
+       }
+
+       return device_node;
+}
+#endif
+
 int _app2sd_create_loopback_device(const char *pkgid,
                const char *loopback_device, int size)
 {
@@ -494,6 +707,7 @@ int _app2sd_mount_app_content(const char *application_path, const char *pkgid,
        int fd = -1;
        char application_mmc_path[FILENAME_MAX] = { 0, };
        char temp_path[FILENAME_MAX] = { 0, };
+       char err_buf[1024] = {0,};
        struct timespec time = {
                .tv_sec = 0,
                .tv_nsec = 1000 * 1000 * 200
@@ -565,7 +779,8 @@ int _app2sd_mount_app_content(const char *application_path, const char *pkgid,
                if ((ret = mount(dev, application_mmc_path, FS_TYPE,
                        MS_MGC_VAL | MS_REMOUNT | MS_NOSUID, NULL)) < 0) {
                        _E("read write remount failed "
-                               "erro no is (%d)", errno);
+                               "errono(%d), errstr(%s)", errno,
+                               strerror_r(errno, err_buf, sizeof(err_buf)));
                                ret = APP2EXT_ERROR_MOUNT;
                }
                break;
@@ -646,7 +861,9 @@ int _app2sd_move_app_to_external(const char *pkgid, GList *dir_list, uid_t uid)
        int reqd_size = 0;
        int reqd_disk_size = 0;
        char *device_node = NULL;
+#if !defined(_APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION)
        char *devi = NULL;
+#endif
        int free_mmc_mem = 0;
        FILE *fp = NULL;
        GList *list = NULL;
@@ -742,6 +959,21 @@ int _app2sd_move_app_to_external(const char *pkgid, GList *dir_list, uid_t uid)
                _E("loopback node creation failed");
                return ret;
        }
+
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+       ret = _app2sd_dmcrypt_setup_device(pkgid, loopback_device, false, uid);
+       if (ret) {
+               _E("dmcrypt setup device error(%d)", ret);
+               return APP2EXT_ERROR_SETUP_DMCRYPT_DEVICE;
+       }
+
+       ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device, false,
+               uid, &device_node);
+       if (ret) {
+               _E("dmcrypt open device error");
+               return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
+       }
+#else
        /* perform loopback encryption setup */
        device_node = _app2sd_do_loopback_encryption_setup(pkgid,
                loopback_device, uid);
@@ -754,16 +986,19 @@ int _app2sd_move_app_to_external(const char *pkgid, GList *dir_list, uid_t uid)
        devi = _app2sd_find_associated_device_node(loopback_device);
        if (devi == NULL) {
                _E("finding associated device node failed");
-               return APP2EXT_ERROR_DO_LOSETUP;
+               ret = APP2EXT_ERROR_DO_LOSETUP;
+               goto ERR;
        } else {
                free(devi);
                devi = NULL;
        }
+#endif
        /* format the loopback file system */
        ret = _app2sd_create_file_system(device_node);
        if (ret) {
                _E("create ext4 filesystem failed");
-               return APP2EXT_ERROR_CREATE_FS;
+               ret = APP2EXT_ERROR_CREATE_FS;
+               goto ERR;
        }
 
        list = g_list_first(dir_list);
@@ -788,7 +1023,7 @@ int _app2sd_move_app_to_external(const char *pkgid, GList *dir_list, uid_t uid)
                                             temp_dir_path,
                                             application_archive_path);
                                }
-                               return ret;
+                               goto ERR;
                        }
                }
                list = g_list_next(list);
@@ -801,7 +1036,7 @@ int _app2sd_move_app_to_external(const char *pkgid, GList *dir_list, uid_t uid)
                MOUNT_TYPE_RW, dir_list, APP2SD_MOVE_APP_TO_MMC, uid);
        if (ret) {
                _E("mount failed");
-               return ret;
+               goto ERR;
        }
 
        list = g_list_first(dir_list);
@@ -829,12 +1064,12 @@ int _app2sd_move_app_to_external(const char *pkgid, GList *dir_list, uid_t uid)
                                                temp_dir_path,
                                                application_mmc_path, err_buf);
                                }
-                               return ret;
+                               goto ERR;
                        }
                        ret = _app2sd_delete_directory(temp_dir_path);
                        if (ret) {
                                _E("unable to delete (%s)", temp_dir_path);
-                               return ret;
+                               goto ERR;
                        }
                }
                list = g_list_next(list);
@@ -843,25 +1078,38 @@ int _app2sd_move_app_to_external(const char *pkgid, GList *dir_list, uid_t uid)
        ret = _app2sd_delete_directory(application_archive_path);
        if (ret) {
                _E("unable to delete (%s)", application_archive_path);
-               return APP2EXT_ERROR_DELETE_DIRECTORY;
+               ret = APP2EXT_ERROR_DELETE_DIRECTORY;
+               goto ERR;
        }
 
        /* re-mount the loopback encrypted pseudo device on application installation path
         * as with Read Only permission
         */
        ret = _app2sd_unmount_app_content(application_path);
-       if (ret) {
+       if (ret)
                _E("unmount error (%d)", ret);
-               return APP2EXT_ERROR_UNMOUNT;
-       }
+
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+       ret = _app2sd_dmcrypt_close_device(pkgid, uid);
+       if (ret)
+               _E("close dmcrypt device error(%d)", ret);
+#else
        ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
-       if (ret) {
+       if (ret)
                _E("unable to detach loopback setup for (%s)",
                        loopback_device);
-               return APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
-       }
+#endif
 
+       sync();
        return APP2EXT_SUCCESS;
+
+ERR:
+       if (device_node) {
+               free(device_node);
+               device_node = NULL;
+       }
+
+       return ret;
 }
 
 int _app2sd_move_app_to_internal(const char *pkgid, GList *dir_list, uid_t uid)
@@ -958,22 +1206,37 @@ int _app2sd_move_app_to_internal(const char *pkgid, GList *dir_list, uid_t uid)
                return APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY;
        }
 
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+       device_node =
+               _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
+#else
        device_node = _app2sd_find_associated_device_node(loopback_device);
+#endif
        if (NULL == device_node) {
                /* do loopback setup */
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+               ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
+                       false, uid, &device_node);
+               if (ret) {
+                       _E("dmcrypt open device error(%d)", ret);
+                       return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
+               }
+#else
                device_node = _app2sd_do_loopback_encryption_setup(pkgid,
                        loopback_device, uid);
                if (device_node == NULL) {
                        _E("loopback encryption setup failed");
                        return APP2EXT_ERROR_DO_LOSETUP;
                }
+#endif
                /* do mounting */
                ret = _app2sd_mount_app_content(application_path,
                        pkgid, device_node, MOUNT_TYPE_RW,
                        dir_list, APP2SD_MOVE_APP_TO_PHONE, uid);
                if (ret) {
                        _E("mount failed");
-                       return APP2EXT_ERROR_MOUNT_PATH;
+                       ret = APP2EXT_ERROR_MOUNT_PATH;
+                       goto ERR;
                }
        } else {
                /* do re-mounting */
@@ -982,7 +1245,8 @@ int _app2sd_move_app_to_internal(const char *pkgid, GList *dir_list, uid_t uid)
                        dir_list, APP2SD_MOVE_APP_TO_PHONE, uid);
                if (ret) {
                        _E("re-mount failed");
-                       return APP2EXT_ERROR_MOUNT_PATH;
+                       ret = APP2EXT_ERROR_MOUNT_PATH;
+                       goto ERR;
                }
        }
 
@@ -996,7 +1260,8 @@ int _app2sd_move_app_to_internal(const char *pkgid, GList *dir_list, uid_t uid)
                if (errno != EEXIST) {
                        _E("unable to create directory for archiving," \
                                " error(%d)", errno);
-                       return APP2EXT_ERROR_CREATE_DIRECTORY;
+                       ret = APP2EXT_ERROR_CREATE_DIRECTORY;
+                       goto ERR;
                }
        }
 
@@ -1025,7 +1290,7 @@ int _app2sd_move_app_to_internal(const char *pkgid, GList *dir_list, uid_t uid)
                                                temp_dir_path,
                                                application_archive_path, err_buf);
                                }
-                               return ret;
+                               goto ERR;
                        }
 
                        /* delete the symbolic link files [bin, lib, res]*/
@@ -1044,7 +1309,7 @@ int _app2sd_move_app_to_internal(const char *pkgid, GList *dir_list, uid_t uid)
                                                " it is already unlinked",
                                                temp_dir_path);
                                }
-                               return ret;
+                               goto ERR;
                        }
 
                        /* Copy content to destination */
@@ -1066,7 +1331,7 @@ int _app2sd_move_app_to_internal(const char *pkgid, GList *dir_list, uid_t uid)
                                                temp_dir_path,
                                                application_path, err_buf);
                                }
-                               return ret;
+                               goto ERR;
                        }
                }
                list = g_list_next(list);
@@ -1074,33 +1339,33 @@ int _app2sd_move_app_to_internal(const char *pkgid, GList *dir_list, uid_t uid)
 
        _D("copying file completed");
        ret = _app2sd_unmount_app_content(application_path);
-       if (ret) {
+       if (ret)
                _E("unable to unmount SD directory for app (%s)",
                     pkgid);
-               return APP2EXT_ERROR_UNMOUNT;
-       }
+
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+       ret = _app2sd_dmcrypt_close_device(pkgid, uid);
+       if (ret)
+               _E("close dmcrypt device error(%d)", ret);
+#else
        ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
-       if (ret) {
+       if (ret)
                _E("unable to detach loopback setup for (%s)",
                     pkgid);
-               return APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
-       }
+#endif
+
        ret = _app2sd_delete_loopback_device(loopback_device);
-       if (ret) {
+       if (ret)
                _E("unable to delete the loopback device for (%s)",
                     pkgid);
-               return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
-       }
+
        ret = _app2sd_delete_directory(application_mmc_path);
-       if (ret) {
+       if (ret)
                _E("unable to delete (%s)", application_mmc_path);
-               return APP2EXT_ERROR_DELETE_DIRECTORY;
-       }
+
        ret = _app2sd_delete_directory(application_archive_path);
-       if (ret) {
+       if (ret)
                _E("unable to delete (%s)", application_archive_path);
-               return APP2EXT_ERROR_DELETE_DIRECTORY;
-       }
 
        /* remove passwrd from DB */
        ret = _app2sd_initialize_db();
@@ -1112,6 +1377,14 @@ int _app2sd_move_app_to_internal(const char *pkgid, GList *dir_list, uid_t uid)
                _E("cannot remove info from db");
 
        return APP2EXT_SUCCESS;
+
+ERR:
+       if (device_node) {
+               free(device_node);
+               device_node = NULL;
+       }
+
+       return ret;
 }
 
 int _app2sd_usr_move_app(const char *pkgid, app2ext_move_type move_type,
@@ -1191,10 +1464,12 @@ int _app2sd_duplicate_device(const char *pkgid,
                uid_t uid)
 {
        int ret = 0;
-       char *devi = NULL;
        int err_res = 0;
+#if !defined(_APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION)
+       char *devi = NULL;
        char *result = NULL;
        char *passwd = NULL;
+#endif
 
        /* create a new loopback device */
        ret = _app2sd_create_loopback_device(temp_pkgid,
@@ -1204,6 +1479,16 @@ int _app2sd_duplicate_device(const char *pkgid,
                return ret;
        }
 
+       /* perform loopback encryption setup */
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+       dev_node = _app2sd_dmcrypt_duplicate_encryption_setup(pkgid,
+               temp_loopback_device, uid);
+       if (!dev_node) {
+               _E("dmcrypt duplicate encryption setup failed");
+               _app2sd_delete_loopback_device(temp_loopback_device);
+               return APP2EXT_ERROR_SETUP_DMCRYPT_DEVICE;
+       }
+#else
        /* get password for loopback encryption */
        ret = _app2sd_initialize_db();
        if (ret) {
@@ -1227,12 +1512,11 @@ int _app2sd_duplicate_device(const char *pkgid,
                }
        }
 
-       /* perform loopback encryption setup */
        dev_node = _app2sd_do_loopback_duplicate_encryption_setup(pkgid,
                temp_pkgid, temp_loopback_device, passwd, uid);
        if (!dev_node) {
                _E("losetup failed, device node is (%s)", dev_node);
-               _app2sd_delete_loopback_device(loopback_device);
+               _app2sd_delete_loopback_device(temp_loopback_device);
                free(passwd);
                passwd = NULL;
                return APP2EXT_ERROR_DO_LOSETUP;
@@ -1251,6 +1535,7 @@ int _app2sd_duplicate_device(const char *pkgid,
                goto FINISH_OFF;
        }
        _D("losetup SUCCESS");
+#endif
 
        /* format the loopback file system */
        ret = _app2sd_create_file_system(dev_node);
@@ -1271,29 +1556,33 @@ int _app2sd_duplicate_device(const char *pkgid,
                goto FINISH_OFF;
        }
 
+#if !defined(_APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION)
        if (devi) {
                free(devi);
                devi = NULL;
        }
+#endif
 
        return APP2EXT_SUCCESS;
 
 FINISH_OFF:
        if (dev_node) {
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+               ret = _app2sd_dmcrypt_close_device(temp_pkgid, uid);
+               if (ret)
+                       _E("close dmcrypt device error(%d)", ret);
+#else
                result = _app2sd_detach_loop_device(dev_node);
                if (result) {
                        free(result);
                        result = NULL;
                }
-               _app2sd_delete_loopback_device(loopback_device);
+#endif
+               _app2sd_delete_loopback_device(temp_loopback_device);
                free(dev_node);
                dev_node = NULL;
        }
 
-       if (devi) {
-               free(devi);
-               devi = NULL;
-       }
        return err_res;
 }
 
@@ -1322,9 +1611,23 @@ int _app2sd_update_loopback_device_size(const char *pkgid,
        }
 
        /* get the associated device node for SD card applicatione */
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+       old_device_node =
+               _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
+#else
        old_device_node = _app2sd_find_associated_device_node(loopback_device);
+#endif
        if (NULL == old_device_node) {
                /* do loopback setup */
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+               ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
+                       false, uid, &old_device_node);
+               if (ret) {
+                       _E("dmcrypt open device error");
+                       err_res = APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
+                       goto FINISH_OFF;
+               }
+#else
                old_device_node = _app2sd_do_loopback_encryption_setup(pkgid,
                        loopback_device, uid);
                if (old_device_node == NULL) {
@@ -1332,6 +1635,7 @@ int _app2sd_update_loopback_device_size(const char *pkgid,
                        err_res = APP2EXT_ERROR_DO_LOSETUP;
                        goto FINISH_OFF;
                }
+#endif
                /* do mounting */
                ret = _app2sd_mount_app_content(application_path, pkgid,
                        old_device_node, MOUNT_TYPE_RW, dir_list,
@@ -1369,12 +1673,6 @@ int _app2sd_update_loopback_device_size(const char *pkgid,
                err_res = APP2EXT_ERROR_UNMOUNT;
        }
 
-       ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
-       if (ret) {
-               _E("unable to remove loopback setup");
-               err_res = APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
-       }
-
        ret = _app2sd_unmount_app_content(temp_application_path);
        if (ret) {
                _E("unable to unmount the SD application");
@@ -1382,12 +1680,34 @@ int _app2sd_update_loopback_device_size(const char *pkgid,
                goto FINISH_OFF;
        }
 
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+       ret = _app2sd_dmcrypt_close_device(pkgid, uid);
+       if (ret) {
+               _E("close dmcrypt device error(%d)", ret);
+               err_res = APP2EXT_ERROR_CLOSE_DMCRYPT_DEVICE;
+               goto FINISH_OFF;
+       }
+
+       ret = _app2sd_dmcrypt_close_device(temp_pkgid, uid);
+       if (ret) {
+               _E("close dmcrypt device error(%d)", ret);
+               err_res = APP2EXT_ERROR_CLOSE_DMCRYPT_DEVICE;
+               goto FINISH_OFF;
+       }
+#else
+       ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
+       if (ret) {
+               _E("unable to remove loopback setup");
+               err_res = APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
+       }
+
        ret = _app2sd_remove_loopback_encryption_setup(temp_loopback_device);
        if (ret) {
                _E("unable to remove loopback setup");
                err_res = APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
                goto FINISH_OFF;
        }
+#endif
 
        ret = _app2sd_delete_directory(loopback_device);
        if (ret) {
@@ -1418,6 +1738,16 @@ FINISH_OFF:
                old_device_node = NULL;
        }
 
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+       ret = _app2sd_dmcrypt_close_device(pkgid, uid);
+       if (ret)
+               _E("close dmcrypt device error(%d)", ret);
+
+       ret = _app2sd_dmcrypt_close_device(temp_pkgid, uid);
+
+       if (ret)
+               _E("close dmcrypt device error(%d)", ret);
+#else
        ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
        if (ret)
                _E("unable to remove loopback setup");
@@ -1425,6 +1755,7 @@ FINISH_OFF:
        ret = _app2sd_remove_loopback_encryption_setup(temp_loopback_device);
        if (ret)
                _E("unable to remove loopback setup");
+#endif
 
        _app2sd_delete_loopback_device(temp_loopback_device);
 
@@ -1446,9 +1777,15 @@ int _app2sd_force_clean(const char *pkgid, const char *application_path,
                _E("unable to unmount the app content (%d)", ret);
 
        /* detach the loopback encryption setup for the application */
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+       ret = _app2sd_dmcrypt_close_device(pkgid, uid);
+       if (ret)
+               _E("close dmcrypt device error (%d)", ret);
+#else
        ret = _app2sd_remove_all_loopback_encryption_setups(loopback_device);
        if (ret)
                _E("unable to detach the loopback encryption setup for the application");
+#endif
 
        /* delete the loopback device from the SD card */
        ret = _app2sd_delete_loopback_device(loopback_device);
index 0f01c46..dbc6025 100644 (file)
@@ -261,7 +261,6 @@ unsigned long long _app2sd_calculate_file_size(const char *filename)
 char *_app2sd_encrypt_device(const char *device,
        const char *loopback_device, char *passwd)
 {
-       /* TODO : change to dm-crypt */
        const char *argv[] = { "/sbin/losetup", device,
                loopback_device, NULL };
        pid_t pid = 0;
index 61705d0..73d28ee 100644 (file)
@@ -23,6 +23,8 @@ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
 
 SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
 
+ADD_DEFINITIONS("-D_APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION")
+
 ADD_EXECUTABLE(test_app2ext ${SRCS})
 TARGET_LINK_LIBRARIES(test_app2ext app2ext ${pkgs_LDFLAGS})
 SET_TARGET_PROPERTIES(test_app2ext PROPERTIES COMPILE_FLAGS ${CFLAGS} "-fPIE")
index 265ebf5..93070d0 100644 (file)
@@ -43,7 +43,7 @@ app2ext_handle *handle = NULL;
 
 char pkg_ro_content_rpm[3][5] = { "bin", "res", "lib" };
 
-#define COUNT_OF_ERROR_LIST 49
+#define COUNT_OF_ERROR_LIST APP2EXT_ERROR_ENUM_MAX
 char error_list[COUNT_OF_ERROR_LIST][100] = {
        "SUCCESS",
        "APP2EXT_ERROR_UNKNOWN",
@@ -93,7 +93,14 @@ char error_list[COUNT_OF_ERROR_LIST][100] = {
        "APP2EXT_ERROR_MEMORY_ALLOC_FAILED",
        "APP2EXT_ERROR_OPERATION_NOT_PERMITTED",
        "APP2EXT_ERROR_SAME_LOOPBACK_DEVICE_EXISTS",
-       "APP2EXT_ERROR_PKGMGR_ERROR"
+       "APP2EXT_ERROR_PKGMGR_ERROR",
+#ifdef _APPFW_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+       "APP2EXT_ERROR_SETUP_DMCRYPT_DEVICE",
+       "APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE",
+       "APP2EXT_ERROR_CLOSE_DMCRYPT_DEVICE",
+       "APP2EXT_ERROR_FIND_ASSOCIATED_DMCRYPT_DEVICE_NODE",
+       "APP2EXT_ERROR_DMCRYPT_DEVICE_UNAVAILABLE",
+#endif
 };
 
 static void usage(void)