/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// This program takes a file on an ext4 filesystem and produces a list
// of the blocks that file occupies, which enables the file contents
// to be read directly from the block device without mounting the
// filesystem.
//
// If the filesystem is using an encrypted block device, it will also
// read the file and rewrite it to the same blocks of the underlying
// (unencrypted) block device, so the file contents can be read
// without the need for the decryption key.
//
// The output of this program is a "block map" which looks like this:
//
//     /dev/block/platform/msm_sdcc.1/by-name/userdata     # block device
//     49652 4096                        # file size in bytes, block size
//     3                                 # count of block ranges
//     1000 1008                         # block range 0
//     2100 2102                         # ... block range 1
//     30 33                             # ... block range 2
//
// Each block range represents a half-open interval; the line "30 33"
// reprents the blocks [30, 31, 32].
//
// Recovery can take this block map file and retrieve the underlying
// file data to use as an update package.

#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <libgen.h>
#include <linux/fs.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <algorithm>
#include <memory>
#include <vector>

#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <cutils/android_reboot.h>
#include <cutils/properties.h>
#include <fs_mgr.h>

#define LOG_TAG "uncrypt"
#include <log/log.h>

#include "bootloader.h"

#define WINDOW_SIZE 5

static const std::string CACHE_BLOCK_MAP = "/cache/recovery/block.map";
static const std::string COMMAND_FILE = "/cache/recovery/command";
static const std::string STATUS_FILE = "/cache/recovery/uncrypt_status";
static const std::string UNCRYPT_PATH_FILE = "/cache/recovery/uncrypt_file";

static struct fstab* fstab = NULL;

static int write_at_offset(unsigned char* buffer, size_t size, int wfd, off64_t offset) {
    if (TEMP_FAILURE_RETRY(lseek64(wfd, offset, SEEK_SET)) == -1) {
        ALOGE("error seeking to offset %" PRId64 ": %s", offset, strerror(errno));
        return -1;
    }
    if (!android::base::WriteFully(wfd, buffer, size)) {
        ALOGE("error writing offset %" PRId64 ": %s", offset, strerror(errno));
        return -1;
    }
    return 0;
}

static void add_block_to_ranges(std::vector<int>& ranges, int new_block) {
    if (!ranges.empty() && new_block == ranges.back()) {
        // If the new block comes immediately after the current range,
        // all we have to do is extend the current range.
        ++ranges.back();
    } else {
        // We need to start a new range.
        ranges.push_back(new_block);
        ranges.push_back(new_block + 1);
    }
}

static struct fstab* read_fstab() {
    fstab = NULL;

    // The fstab path is always "/fstab.${ro.hardware}".
    char fstab_path[PATH_MAX+1] = "/fstab.";
    if (!property_get("ro.hardware", fstab_path+strlen(fstab_path), "")) {
        ALOGE("failed to get ro.hardware");
        return NULL;
    }

    fstab = fs_mgr_read_fstab(fstab_path);
    if (!fstab) {
        ALOGE("failed to read %s", fstab_path);
        return NULL;
    }

    return fstab;
}

static const char* find_block_device(const char* path, bool* encryptable, bool* encrypted) {
    // Look for a volume whose mount point is the prefix of path and
    // return its block device.  Set encrypted if it's currently
    // encrypted.
    for (int i = 0; i < fstab->num_entries; ++i) {
        struct fstab_rec* v = &fstab->recs[i];
        if (!v->mount_point) {
            continue;
        }
        int len = strlen(v->mount_point);
        if (strncmp(path, v->mount_point, len) == 0 &&
            (path[len] == '/' || path[len] == 0)) {
            *encrypted = false;
            *encryptable = false;
            if (fs_mgr_is_encryptable(v) || fs_mgr_is_file_encrypted(v)) {
                *encryptable = true;
                char buffer[PROPERTY_VALUE_MAX+1];
                if (property_get("ro.crypto.state", buffer, "") &&
                    strcmp(buffer, "encrypted") == 0) {
                    *encrypted = true;
                }
            }
            return v->blk_device;
        }
    }

    return NULL;
}

// Parse uncrypt_file to find the update package name.
static bool find_uncrypt_package(const std::string& uncrypt_path_file, std::string* package_name) {
    CHECK(package_name != nullptr);
    std::string uncrypt_path;
    if (!android::base::ReadFileToString(uncrypt_path_file, &uncrypt_path)) {
        ALOGE("failed to open \"%s\": %s", uncrypt_path_file.c_str(), strerror(errno));
        return false;
    }

    // Remove the trailing '\n' if present.
    *package_name = android::base::Trim(uncrypt_path);
    return true;
}

static int produce_block_map(const char* path, const char* map_file, const char* blk_dev,
                             bool encrypted, int status_fd) {
    std::string err;
    if (!android::base::RemoveFileIfExists(map_file, &err)) {
        ALOGE("failed to remove the existing map file %s: %s", map_file, err.c_str());
        return -1;
    }
    std::string tmp_map_file = std::string(map_file) + ".tmp";
    android::base::unique_fd mapfd(open(tmp_map_file.c_str(),
                                        O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR));
    if (mapfd == -1) {
        ALOGE("failed to open %s: %s\n", tmp_map_file.c_str(), strerror(errno));
        return -1;
    }

    // Make sure we can write to the status_file.
    if (!android::base::WriteStringToFd("0\n", status_fd)) {
        ALOGE("failed to update \"%s\"\n", STATUS_FILE.c_str());
        return -1;
    }

    struct stat sb;
    if (stat(path, &sb) != 0) {
        ALOGE("failed to stat %s", path);
        return -1;
    }

    ALOGI(" block size: %ld bytes", static_cast<long>(sb.st_blksize));

    int blocks = ((sb.st_size-1) / sb.st_blksize) + 1;
    ALOGI("  file size: %" PRId64 " bytes, %d blocks", sb.st_size, blocks);

    std::vector<int> ranges;

    std::string s = android::base::StringPrintf("%s\n%" PRId64 " %" PRId64 "\n",
                       blk_dev, static_cast<int64_t>(sb.st_size),
                       static_cast<int64_t>(sb.st_blksize));
    if (!android::base::WriteStringToFd(s, mapfd)) {
        ALOGE("failed to write %s: %s", tmp_map_file.c_str(), strerror(errno));
        return -1;
    }

    std::vector<std::vector<unsigned char>> buffers;
    if (encrypted) {
        buffers.resize(WINDOW_SIZE, std::vector<unsigned char>(sb.st_blksize));
    }
    int head_block = 0;
    int head = 0, tail = 0;

    android::base::unique_fd fd(open(path, O_RDONLY));
    if (fd == -1) {
        ALOGE("failed to open %s for reading: %s", path, strerror(errno));
        return -1;
    }

    android::base::unique_fd wfd;
    if (encrypted) {
        wfd.reset(open(blk_dev, O_WRONLY));
        if (wfd == -1) {
            ALOGE("failed to open fd for writing: %s", strerror(errno));
            return -1;
        }
    }

    off64_t pos = 0;
    int last_progress = 0;
    while (pos < sb.st_size) {
        // Update the status file, progress must be between [0, 99].
        int progress = static_cast<int>(100 * (double(pos) / double(sb.st_size)));
        if (progress > last_progress) {
          last_progress = progress;
          android::base::WriteStringToFd(std::to_string(progress) + "\n", status_fd);
        }

        if ((tail+1) % WINDOW_SIZE == head) {
            // write out head buffer
            int block = head_block;
            if (ioctl(fd, FIBMAP, &block) != 0) {
                ALOGE("failed to find block %d", head_block);
                return -1;
            }
            add_block_to_ranges(ranges, block);
            if (encrypted) {
                if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd,
                                    static_cast<off64_t>(sb.st_blksize) * block) != 0) {
                    return -1;
                }
            }
            head = (head + 1) % WINDOW_SIZE;
            ++head_block;
        }

        // read next block to tail
        if (encrypted) {
            size_t to_read = static_cast<size_t>(
                    std::min(static_cast<off64_t>(sb.st_blksize), sb.st_size - pos));
            if (!android::base::ReadFully(fd, buffers[tail].data(), to_read)) {
                ALOGE("failed to read: %s", strerror(errno));
                return -1;
            }
            pos += to_read;
        } else {
            // If we're not encrypting; we don't need to actually read
            // anything, just skip pos forward as if we'd read a
            // block.
            pos += sb.st_blksize;
        }
        tail = (tail+1) % WINDOW_SIZE;
    }

    while (head != tail) {
        // write out head buffer
        int block = head_block;
        if (ioctl(fd, FIBMAP, &block) != 0) {
            ALOGE("failed to find block %d", head_block);
            return -1;
        }
        add_block_to_ranges(ranges, block);
        if (encrypted) {
            if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd,
                                static_cast<off64_t>(sb.st_blksize) * block) != 0) {
                return -1;
            }
        }
        head = (head + 1) % WINDOW_SIZE;
        ++head_block;
    }

    if (!android::base::WriteStringToFd(
            android::base::StringPrintf("%zu\n", ranges.size() / 2), mapfd)) {
        ALOGE("failed to write %s: %s", tmp_map_file.c_str(), strerror(errno));
        return -1;
    }
    for (size_t i = 0; i < ranges.size(); i += 2) {
        if (!android::base::WriteStringToFd(
                android::base::StringPrintf("%d %d\n", ranges[i], ranges[i+1]), mapfd)) {
            ALOGE("failed to write %s: %s", tmp_map_file.c_str(), strerror(errno));
            return -1;
        }
    }

    if (fsync(mapfd) == -1) {
        ALOGE("failed to fsync \"%s\": %s", tmp_map_file.c_str(), strerror(errno));
        return -1;
    }
    if (close(mapfd.release()) == -1) {
        ALOGE("failed to close %s: %s", tmp_map_file.c_str(), strerror(errno));
        return -1;
    }

    if (encrypted) {
        if (fsync(wfd) == -1) {
            ALOGE("failed to fsync \"%s\": %s", blk_dev, strerror(errno));
            return -1;
        }
        if (close(wfd.release()) == -1) {
            ALOGE("failed to close %s: %s", blk_dev, strerror(errno));
            return -1;
        }
    }

    if (rename(tmp_map_file.c_str(), map_file) == -1) {
        ALOGE("failed to rename %s to %s: %s", tmp_map_file.c_str(), map_file, strerror(errno));
        return -1;
    }
    // Sync dir to make rename() result written to disk.
    std::string file_name = map_file;
    std::string dir_name = dirname(&file_name[0]);
    android::base::unique_fd dfd(open(dir_name.c_str(), O_RDONLY | O_DIRECTORY));
    if (dfd == -1) {
        ALOGE("failed to open dir %s: %s", dir_name.c_str(), strerror(errno));
        return -1;
    }
    if (fsync(dfd) == -1) {
        ALOGE("failed to fsync %s: %s", dir_name.c_str(), strerror(errno));
        return -1;
    }
    if (close(dfd.release()) == -1) {
        ALOGE("failed to close %s: %s", dir_name.c_str(), strerror(errno));
        return -1;
    }
    return 0;
}

static std::string get_misc_blk_device() {
    struct fstab* fstab = read_fstab();
    if (fstab == nullptr) {
        return "";
    }
    for (int i = 0; i < fstab->num_entries; ++i) {
        fstab_rec* v = &fstab->recs[i];
        if (v->mount_point != nullptr && strcmp(v->mount_point, "/misc") == 0) {
            return v->blk_device;
        }
    }
    return "";
}

static int write_bootloader_message(const bootloader_message* in) {
    std::string misc_blk_device = get_misc_blk_device();
    if (misc_blk_device.empty()) {
        ALOGE("failed to find /misc partition.");
        return -1;
    }
    android::base::unique_fd fd(open(misc_blk_device.c_str(), O_WRONLY | O_SYNC));
    if (fd == -1) {
        ALOGE("failed to open %s: %s", misc_blk_device.c_str(), strerror(errno));
        return -1;
    }
    if (!android::base::WriteFully(fd, in, sizeof(*in))) {
        ALOGE("failed to write %s: %s", misc_blk_device.c_str(), strerror(errno));
        return -1;
    }
    // TODO: O_SYNC and fsync() duplicates each other?
    if (fsync(fd) == -1) {
        ALOGE("failed to fsync %s: %s", misc_blk_device.c_str(), strerror(errno));
        return -1;
    }
    return 0;
}

static void reboot_to_recovery() {
    ALOGI("rebooting to recovery");
    property_set("sys.powerctl", "reboot,recovery");
    while (true) {
      pause();
    }
    ALOGE("reboot didn't succeed?");
}

static int uncrypt(const char* input_path, const char* map_file, int status_fd) {

    ALOGI("update package is \"%s\"", input_path);

    // Turn the name of the file we're supposed to convert into an
    // absolute path, so we can find what filesystem it's on.
    char path[PATH_MAX+1];
    if (realpath(input_path, path) == NULL) {
        ALOGE("failed to convert \"%s\" to absolute path: %s", input_path, strerror(errno));
        return 1;
    }

    if (read_fstab() == NULL) {
        return 1;
    }

    bool encryptable;
    bool encrypted;
    const char* blk_dev = find_block_device(path, &encryptable, &encrypted);
    if (blk_dev == NULL) {
        ALOGE("failed to find block device for %s", path);
        return 1;
    }

    // If the filesystem it's on isn't encrypted, we only produce the
    // block map, we don't rewrite the file contents (it would be
    // pointless to do so).
    ALOGI("encryptable: %s", encryptable ? "yes" : "no");
    ALOGI("  encrypted: %s", encrypted ? "yes" : "no");

    // Recovery supports installing packages from 3 paths: /cache,
    // /data, and /sdcard.  (On a particular device, other locations
    // may work, but those are three we actually expect.)
    //
    // On /data we want to convert the file to a block map so that we
    // can read the package without mounting the partition.  On /cache
    // and /sdcard we leave the file alone.
    if (strncmp(path, "/data/", 6) == 0) {
        ALOGI("writing block map %s", map_file);
        if (produce_block_map(path, map_file, blk_dev, encrypted, status_fd) != 0) {
            return 1;
        }
    }

    return 0;
}

static int uncrypt_wrapper(const char* input_path, const char* map_file,
                           const std::string& status_file) {
    // The pipe has been created by the system server.
    android::base::unique_fd status_fd(open(status_file.c_str(),
                                            O_WRONLY | O_CREAT | O_SYNC, S_IRUSR | S_IWUSR));
    if (status_fd == -1) {
        ALOGE("failed to open pipe \"%s\": %s", status_file.c_str(), strerror(errno));
        return 1;
    }

    std::string package;
    if (input_path == nullptr) {
        if (!find_uncrypt_package(UNCRYPT_PATH_FILE, &package)) {
            android::base::WriteStringToFd("-1\n", status_fd);
            return 1;
        }
        input_path = package.c_str();
    }
    CHECK(map_file != nullptr);
    int status = uncrypt(input_path, map_file, status_fd);
    if (status != 0) {
        android::base::WriteStringToFd("-1\n", status_fd);
        return 1;
    }
    android::base::WriteStringToFd("100\n", status_fd);
    return 0;
}

static int clear_bcb(const std::string& status_file) {
    android::base::unique_fd status_fd(open(status_file.c_str(),
                                            O_WRONLY | O_CREAT | O_SYNC, S_IRUSR | S_IWUSR));
    if (status_fd == -1) {
        ALOGE("failed to open pipe \"%s\": %s", status_file.c_str(), strerror(errno));
        return 1;
    }
    bootloader_message boot = {};
    if (write_bootloader_message(&boot) != 0) {
        android::base::WriteStringToFd("-1\n", status_fd);
        return 1;
    }
    android::base::WriteStringToFd("100\n", status_fd);
    return 0;
}

static int setup_bcb(const std::string& command_file, const std::string& status_file) {
    android::base::unique_fd status_fd(open(status_file.c_str(),
                                            O_WRONLY | O_CREAT | O_SYNC, S_IRUSR | S_IWUSR));
    if (status_fd == -1) {
        ALOGE("failed to open pipe \"%s\": %s", status_file.c_str(), strerror(errno));
        return 1;
    }
    std::string content;
    if (!android::base::ReadFileToString(command_file, &content)) {
        ALOGE("failed to read \"%s\": %s", command_file.c_str(), strerror(errno));
        android::base::WriteStringToFd("-1\n", status_fd);
        return 1;
    }
    bootloader_message boot = {};
    strlcpy(boot.command, "boot-recovery", sizeof(boot.command));
    strlcpy(boot.recovery, "recovery\n", sizeof(boot.recovery));
    strlcat(boot.recovery, content.c_str(), sizeof(boot.recovery));
    if (write_bootloader_message(&boot) != 0) {
        ALOGE("failed to set bootloader message");
        android::base::WriteStringToFd("-1\n", status_fd);
        return 1;
    }
    android::base::WriteStringToFd("100\n", status_fd);
    return 0;
}

static void usage(const char* exename) {
    fprintf(stderr, "Usage of %s:\n", exename);
    fprintf(stderr, "%s [<package_path> <map_file>]  Uncrypt ota package.\n", exename);
    fprintf(stderr, "%s --reboot  Clear BCB data and reboot to recovery.\n", exename);
    fprintf(stderr, "%s --clear-bcb  Clear BCB data in misc partition.\n", exename);
    fprintf(stderr, "%s --setup-bcb  Setup BCB data by command file.\n", exename);
}

int main(int argc, char** argv) {
    if (argc == 2) {
        if (strcmp(argv[1], "--reboot") == 0) {
            reboot_to_recovery();
        } else if (strcmp(argv[1], "--clear-bcb") == 0) {
            return clear_bcb(STATUS_FILE);
        } else if (strcmp(argv[1], "--setup-bcb") == 0) {
            return setup_bcb(COMMAND_FILE, STATUS_FILE);
        }
    } else if (argc == 1 || argc == 3) {
        const char* input_path = nullptr;
        const char* map_file = CACHE_BLOCK_MAP.c_str();
        if (argc == 3) {
            input_path = argv[1];
            map_file = argv[2];
        }
        return uncrypt_wrapper(input_path, map_file, STATUS_FILE);
    }
    usage(argv[0]);
    return 2;
}
