Example #1
0
/*
 * Worker thread for init to make sure the QFS is mounted, if not
 * attempt to mount it about 2 times and then give up.
 *
 * Return: success = 0 [or] failure = 1
 */
static int
hasamInitWorker(
	int argc,
	char **argv,
	struct FsInfo_4hasam *fp)
{
	int i, rc;
	boolean_t mnt_status;

	if (!fp->fi_fs || !fp->fi_mntpt) {
		return (1);
	}

	for (i = 0; i < 2; i++) {
		/* Check if the given QFS is mounted */
		mnt_status = check_fs_mounted(fp->fi_fs);
		if (mnt_status == B_FALSE) {
			/* FS not mounted, attempt to mount the QFS */
			if ((rc = mount_fs_4hasam(fp->fi_fs)) != 0) {
				/* 22685 */
				scds_syslog(LOG_ERR,
				    "%s: Error mounting %s.",
				    fp->fi_fs, fp->fi_mntpt);
			} else {
				sleep(3);
			}
		} else {
			break;
		}
	}

	if (mnt_status == B_FALSE) {
		dprintf(stderr, "Error FS not mounted %s !\n", fp->fi_fs);
		return (1);
	}

	return (rc == 0 ? 0 : 1);
}
/**
 * Mount encrypted data for an Android user
 *
 * @param user Android user id
 * @param password Android user password
 *
 * @return 0 on success, negative value on error
 */
int android_unlock_user_data(int user, char *password)
{
    char storage_path[MAX_PATH_LENGTH];
    char private_dir_path[MAX_PATH_LENGTH];
    int ret = -1;

    LOGI("Unlock user %d", user);

    if (user == PRIMARY_USER) {
        ret = android_unlock_primary_user(password);
        return ret;
    }

    memset(storage_path, 0, sizeof(storage_path));
    sprintf(storage_path, "%s%d", ANDROID_USER_DATA_PATH, user);

    ret = get_private_storage_path(private_dir_path, storage_path);
    if (ret < 0) {
        LOGE("Error getting private storage for %s", storage_path);
        return ret;
    }

    ret = access(private_dir_path, F_OK);
    if (ret < 0) {
        LOGE("Private storage %s does not exist", private_dir_path);
        return ret;
    }

    if (check_fs_mounted(private_dir_path) == 1) {
        LOGE("ecryptfs is already mounted on %s", storage_path);
        return 0;
    }

    ret = remove_dir_content(storage_path);
    if (ret < 0) {
        LOGE("Error removing data from %s directory", storage_path);
        return ret;
    }

    ret = EFS_unlock(storage_path, password);
    if (ret < 0) {
        LOGE("Error unlocking efs storage %s", storage_path);
        return ret;
    }

    memset(storage_path, 0, sizeof(storage_path));
    sprintf(storage_path, "%s%d", ANDROID_VIRTUAL_SDCARD_PATH, user);

    if (check_fs_mounted(storage_path) == 1) {
        LOGE("ecryptfs is already mounted on %s", storage_path);
        return 0;
    }

    ret = remove_dir_content(storage_path);
    if (ret < 0) {
        LOGE("Error removing data from %s directory", storage_path);
        return ret;
    }

    ret = EFS_unlock(storage_path, password);
    if (ret < 0) {
        LOGE("Error unlocking efs storage %s", storage_path);
        return ret;
    }

    return 0;
}
static int android_unlock_primary_user(char *password)
{
    char storage_path[MAX_PATH_LENGTH];
    char private_dir_path[MAX_PATH_LENGTH];
    struct crypto_header header;
    int ret;

    ret = read_crypto_header(&header, CRYPTO_HEADER_COPY);
    if (ret < 0)
        return ret;

    ret = check_passwd(&header, password);
    if (ret < 0)
        return ret;

    property_set("vold.decrypt", "trigger_reset_main");
    sleep(2);
    umount("/data", MNT_FORCE);

    memset(storage_path, 0, sizeof(storage_path));
    sprintf(storage_path, "%s%d", ANDROID_USER_DATA_PATH, PRIMARY_USER);

    ret = get_private_storage_path(private_dir_path, storage_path);
    if (ret < 0) {
        LOGE("Error getting private storage for %s", storage_path);
        return ret;
    }

    ret = access(private_dir_path, F_OK);
    if (ret < 0) {
        LOGE("Private storage %s does not exist", private_dir_path);
        return ret;
    }

    if (check_fs_mounted(private_dir_path) == 1) {
        LOGE("ecryptfs is already mounted on %s", storage_path);
        return 0;
    }

    ret = remove_dir_content(storage_path);
    if (ret < 0) {
        LOGE("Error removing data from %s directory", storage_path);
        return ret;
    }

    ret = EFS_unlock(storage_path, password);
    if (ret < 0) {
        LOGE("Error unlocking efs storage %s", storage_path);
        return ret;
    }

    memset(storage_path, 0, sizeof(storage_path));
    sprintf(storage_path, "%s%d", ANDROID_VIRTUAL_SDCARD_PATH,
        PRIMARY_USER);

    if (check_fs_mounted(storage_path) == 1) {
        LOGE("ecryptfs is already mounted on %s", storage_path);
        return 0;
    }

    ret = remove_dir_content(storage_path);
    if (ret < 0) {
        LOGE("Error removing data from %s directory", storage_path);
        return ret;
    }

    ret = EFS_unlock(storage_path, password);
    if (ret < 0) {
        LOGE("Error unlocking efs storage %s", storage_path);
        return ret;
    }

    property_set("crypto.primary_user", "decrypted");
    sleep(2);
    property_set("vold.decrypt", "trigger_restart_framework");

    return 0;
}