/* Copyright 2019 The ChromiumOS Authors
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 * The utility functions for firmware updater.
 */

#include <assert.h>
#include <limits.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#if defined (__FreeBSD__) || defined(__OpenBSD__)
#include <sys/wait.h>
#endif

#include "2common.h"
#include "host_misc.h"
#include "util_misc.h"
#include "updater.h"

#define COMMAND_BUFFER_SIZE 256

/*
 * Strips a string (usually from shell execution output) by removing all the
 * trailing characters in pattern. If pattern is NULL, match by space type
 * characters (space, new line, tab, ... etc).
 */
void strip_string(char *s, const char *pattern)
{
	int len;
	assert(s);

	len = strlen(s);
	while (len-- > 0) {
		if (pattern) {
			if (!strchr(pattern, s[len]))
				break;
		} else {
			if (!isascii(s[len]) || !isspace(s[len]))
				break;
		}
		s[len] = '\0';
	}
}

/*
 * Saves everything from stdin to given output file.
 * Returns 0 on success, otherwise failure.
 */
int save_file_from_stdin(const char *output)
{
	FILE *in = stdin, *out = fopen(output, "wb");
	char buffer[4096];
	size_t sz;

	assert(in);
	if (!out)
		return -1;

	while (!feof(in)) {
		sz = fread(buffer, 1, sizeof(buffer), in);
		if (fwrite(buffer, 1, sz, out) != sz) {
			fclose(out);
			return -1;
		}
	}
	fclose(out);
	return 0;
}

/*
 * Returns 1 if a given file (cbfs_entry_name) exists inside a particular CBFS
 * section of an image file, otherwise 0.
 */
int cbfs_file_exists(const char *image_file,
		     const char *section_name,
		     const char *cbfs_entry_name)
{
	char *cmd;
	int r;

	ASPRINTF(&cmd,
		 "cbfstool '%s' print -r %s 2>/dev/null | grep -q '^%s '",
		 image_file, section_name, cbfs_entry_name);
	r = system(cmd);
	free(cmd);
	return !r;
}

/*
 * Extracts files from a CBFS on given region (section) of image_file.
 * Returns the path to a temporary file on success, otherwise NULL.
 */
const char *cbfs_extract_file(const char *image_file,
			      const char *cbfs_region,
			      const char *cbfs_name,
			      struct tempfile *tempfiles)
{
	const char *output = create_temp_file(tempfiles);
	char *command, *result;

	if (!output)
		return NULL;

	ASPRINTF(&command, "cbfstool \"%s\" extract -r %s -n \"%s\" "
		 "-f \"%s\" 2>&1", image_file, cbfs_region,
		 cbfs_name, output);

	result = host_shell(command);
	free(command);

	if (!*result)
		output = NULL;

	free(result);
	return output;
}

/*
 * Loads the firmware information from an FMAP section in loaded firmware image.
 * The section should only contain ASCIIZ string as firmware version.
 * Returns 0 if a non-empty version string is stored in *version, otherwise -1.
 */
static int load_firmware_version(struct firmware_image *image,
				 const char *section_name,
				 char **version)
{
	struct firmware_section fwid;
	int len = 0;

	/*
	 * section_name is NULL when parsing the RW versions on a non-vboot
	 * image (and already warned in load_firmware_image). We still need to
	 * initialize *version with empty string.
	 */
	if (section_name) {
		find_firmware_section(&fwid, image, section_name);
		if (fwid.size)
			len = fwid.size;
		else
			WARN("No valid section '%s', missing version info.\n",
			     section_name);
	}

	if (!len) {
		*version = strdup("");
		return -1;
	}

	/*
	 * For 'system current' images, the version string may contain
	 * invalid characters that we do want to strip.
	 */
	*version = strndup((const char *)fwid.data, len);
	strip_string(*version, "\xff");
	return 0;
}

/*
 * Fills in the other fields of image using image->data.
 * Returns IMAGE_LOAD_SUCCESS or IMAGE_PARSE_FAILURE.
 */
static int parse_firmware_image(struct firmware_image *image)
{
	int ret = IMAGE_LOAD_SUCCESS;
	const char *section_a = NULL, *section_b = NULL;

	VB2_DEBUG("Image size: %d\n", image->size);
	assert(image->data);

	image->fmap_header = fmap_find(image->data, image->size);

	if (!image->fmap_header) {
		ERROR("Invalid image file (missing FMAP): %s\n", image->file_name);
		ret = IMAGE_PARSE_FAILURE;
	}

	if (load_firmware_version(image, FMAP_RO_FRID, &image->ro_version))
		ret = IMAGE_PARSE_FAILURE;

	if (firmware_section_exists(image, FMAP_RW_FWID_A)) {
		section_a = FMAP_RW_FWID_A;
		section_b = FMAP_RW_FWID_B;
	} else if (firmware_section_exists(image, FMAP_RW_FWID)) {
		section_a = FMAP_RW_FWID;
		section_b = FMAP_RW_FWID;
	} else if (!ret) {
		ERROR("Unsupported VBoot firmware (no RW ID): %s\n", image->file_name);
		ret = IMAGE_PARSE_FAILURE;
	}

	/*
	 * Load and initialize both RW A and B sections.
	 * Note some unit tests will create only RW A.
	 */
	load_firmware_version(image, section_a, &image->rw_version_a);
	load_firmware_version(image, section_b, &image->rw_version_b);

	return ret;
}

/*
 * Loads a firmware image from file.
 * If archive is provided and file_name is a relative path, read the file from
 * archive.
 * Returns IMAGE_LOAD_SUCCESS on success, IMAGE_READ_FAILURE on file I/O
 * failure, or IMAGE_PARSE_FAILURE for non-vboot images.
 */
int load_firmware_image(struct firmware_image *image, const char *file_name,
			struct u_archive *archive)
{
	if (!file_name) {
		ERROR("No file name given\n");
		return IMAGE_READ_FAILURE;
	}

	VB2_DEBUG("Load image file from %s...\n", file_name);

	if (!archive_has_entry(archive, file_name)) {
		ERROR("Does not exist: %s\n", file_name);
		return IMAGE_READ_FAILURE;
	}
	if (archive_read_file(archive, file_name, &image->data, &image->size,
			      NULL) != VB2_SUCCESS) {
		ERROR("Failed to load %s\n", file_name);
		return IMAGE_READ_FAILURE;
	}

	image->file_name = strdup(file_name);

	return parse_firmware_image(image);
}

/*
 * Generates a temporary file for snapshot of firmware image contents.
 *
 * Returns a file path if success, otherwise NULL.
 */
const char *get_firmware_image_temp_file(const struct firmware_image *image,
					 struct tempfile *tempfiles)
{
	const char *tmp_path = create_temp_file(tempfiles);
	if (!tmp_path)
		return NULL;

	if (vb2_write_file(tmp_path, image->data, image->size) != VB2_SUCCESS) {
		ERROR("Failed writing %s firmware image (%u bytes) to %s.\n",
		      image->programmer ? image->programmer : "temp",
		      image->size, tmp_path);
		return NULL;
	}
	return tmp_path;
}

/*
 * Frees the allocated resource from a firmware image object.
 */
void free_firmware_image(struct firmware_image *image)
{
	/*
	 * The programmer is not allocated by load_firmware_image and must be
	 * preserved explicitly.
	 */
	const char *programmer = image->programmer;

	free(image->data);
	free(image->file_name);
	free(image->ro_version);
	free(image->rw_version_a);
	free(image->rw_version_b);
	memset(image, 0, sizeof(*image));
	image->programmer = programmer;
}

/* Preserves meta data and reloads image contents from given file path. */
int reload_firmware_image(const char *file_path, struct firmware_image *image)
{
	free_firmware_image(image);
	return load_firmware_image(image, file_path, NULL);
}

/*
 * Finds a firmware section by given name in the firmware image.
 * If successful, return zero and *section argument contains the address and
 * size of the section; otherwise failure.
 */
int find_firmware_section(struct firmware_section *section,
			  const struct firmware_image *image,
			  const char *section_name)
{
	FmapAreaHeader *fah = NULL;
	uint8_t *ptr;

	section->data = NULL;
	section->size = 0;
	ptr = fmap_find_by_name(
			image->data, image->size, image->fmap_header,
			section_name, &fah);
	if (!ptr)
		return -1;
	section->data = (uint8_t *)ptr;
	section->size = fah->area_size;
	return 0;
}

/*
 * Returns true if the given FMAP section exists in the firmware image.
 */
int firmware_section_exists(const struct firmware_image *image,
			    const char *section_name)
{
	struct firmware_section section;
	find_firmware_section(&section, image, section_name);
	return section.data != NULL;
}

/*
 * Preserves (copies) the given section (by name) from image_from to image_to.
 * The offset may be different, and the section data will be directly copied.
 * If the section does not exist on either images, return as failure.
 * If the source section is larger, contents on destination be truncated.
 * If the source section is smaller, the remaining area is not modified.
 * Returns 0 if success, non-zero if error.
 */
int preserve_firmware_section(const struct firmware_image *image_from,
			      struct firmware_image *image_to,
			      const char *section_name)
{
	struct firmware_section from, to;

	find_firmware_section(&from, image_from, section_name);
	find_firmware_section(&to, image_to, section_name);
	if (!from.data || !to.data) {
		VB2_DEBUG("Cannot find section %.*s: from=%p, to=%p\n",
			  FMAP_NAMELEN, section_name, from.data, to.data);
		return -1;
	}
	if (from.size > to.size) {
		WARN("Section %.*s is truncated after updated.\n",
		     FMAP_NAMELEN, section_name);
	}
	/* Use memmove in case if we need to deal with sections that overlap. */
	memmove(to.data, from.data, VB2_MIN(from.size, to.size));
	return 0;
}

/*
 * Finds the GBB (Google Binary Block) header on a given firmware image.
 * Returns a pointer to valid GBB header, or NULL on not found.
 */
const struct vb2_gbb_header *find_gbb(const struct firmware_image *image)
{
	struct firmware_section section;
	struct vb2_gbb_header *gbb_header;

	find_firmware_section(&section, image, FMAP_RO_GBB);
	gbb_header = (struct vb2_gbb_header *)section.data;
	if (!futil_valid_gbb_header(gbb_header, section.size, NULL)) {
		ERROR("Cannot find GBB in image: %s.\n", image->file_name);
		return NULL;
	}
	return gbb_header;
}

/*
 * Different settings may have different SWWP programmers.
 */
static bool is_write_protection_enabled(struct updater_config *cfg,
					const char *programmer,
					enum dut_property_type swwp_type)
{
	/* Assume HW/SW WP are enabled if -1 error code is returned */
	bool hwwp = !!dut_get_property(DUT_PROP_WP_HW, cfg);
	bool swwp = !!dut_get_property(swwp_type, cfg);
	bool wp_enabled = hwwp && swwp;
	STATUS("Write protection (%s): %d (%s; HW=%d, SW=%d).\n", programmer,
	       wp_enabled, wp_enabled ? "enabled" : "disabled", hwwp, swwp);
	return wp_enabled;
}

/*
 * Returns true if the AP write protection is enabled on current system.
 */
inline bool is_ap_write_protection_enabled(struct updater_config *cfg)
{
	return is_write_protection_enabled(cfg, cfg->image.programmer, DUT_PROP_WP_SW_AP);
}

/*
 * Returns true if the EC write protection is enabled on current system.
 */
inline bool is_ec_write_protection_enabled(struct updater_config *cfg)
{
	return is_write_protection_enabled(cfg, cfg->ec_image.programmer, DUT_PROP_WP_SW_EC);
}

/*
 * Executes a command on current host and returns stripped command output.
 * If the command has failed (exit code is not zero), returns an empty string.
 * The caller is responsible for releasing the returned string.
 */
char *host_shell(const char *command)
{
	/* Currently all commands we use do not have large output. */
	char buf[COMMAND_BUFFER_SIZE];

	int result;
	FILE *fp = popen(command, "r");

	VB2_DEBUG("%s\n", command);
	buf[0] = '\0';
	if (!fp) {
		VB2_DEBUG("Execution error for %s.\n", command);
		return strdup(buf);
	}

	if (fgets(buf, sizeof(buf), fp))
		strip_string(buf, NULL);
	result = pclose(fp);
	if (!WIFEXITED(result) || WEXITSTATUS(result) != 0) {
		VB2_DEBUG("Execution failure with exit code %d: %s\n",
			  WEXITSTATUS(result), command);
		/*
		 * Discard all output if command failed, for example command
		 * syntax failure may lead to garbage in stdout.
		 */
		buf[0] = '\0';
	}
	return strdup(buf);
}

void prepare_servo_control(const char *control_name, bool on)
{
	char *cmd;
	if (!control_name)
		return;

	ASPRINTF(&cmd, "dut-control %s:%s", control_name, on ? "on" : "off");
	free(host_shell(cmd));
	free(cmd);
}

/*
 * Helper function to detect type of Servo board attached to host.
 * Returns a string as programmer parameter on success, otherwise NULL.
 */
char *host_detect_servo(const char **prepare_ctrl_name)
{
	const char *servo_port = getenv(ENV_SERVOD_PORT);
	const char *servo_name = getenv(ENV_SERVOD_NAME);
	const char *servo_id = servo_port, *servo_id_type = ENV_SERVOD_PORT;
	char *servo_type = host_shell("dut-control -o servo_type 2>/dev/null");
	const char *programmer = NULL;
	char *ret = NULL;
	char *servo_serial = NULL;

	static const char * const raiden_debug_spi = "raiden_debug_spi";
	static const char * const cpu_fw_spi = "cpu_fw_spi";
	static const char * const ccd_cpu_fw_spi = "ccd_cpu_fw_spi";
	const char *serial_cmd = "dut-control -o serialname 2>/dev/null";

	/* By default, no control is needed. */
	*prepare_ctrl_name = NULL;
	VB2_DEBUG("servo_type: %s\n", servo_type);

	/* dut-control defaults to port 9999, or non-empty servo_name. */
	if (!servo_id || !*servo_id) {
		if (servo_name && *servo_name) {
			servo_id = servo_name;
			servo_id_type = ENV_SERVOD_NAME;
		} else {
			servo_id = "9999";
		}
	}
	assert(servo_id && *servo_id);

	/* servo_type names: chromite/lib/firmware/servo_lib.py */
	if (!*servo_type) {
		ERROR("Failed to get servo type. Check servod.\n");
	} else if (strcmp(servo_type, "servo_v2") == 0) {
		VB2_DEBUG("Selected Servo V2.\n");
		programmer = "ft2232_spi:type=google-servo-v2";
		*prepare_ctrl_name = cpu_fw_spi;
	} else if (strstr(servo_type, "servo_micro")) {
		VB2_DEBUG("Selected Servo Micro.\n");
		programmer = raiden_debug_spi;
		*prepare_ctrl_name = cpu_fw_spi;
		serial_cmd = ("dut-control -o servo_micro_serialname"
			" 2>/dev/null");
	} else if (strstr(servo_type, "ccd_cr50") ||
		   strstr(servo_type, "ccd_gsc") ||
		   strstr(servo_type, "ccd_ti50")) {
		VB2_DEBUG("Selected CCD.\n");
		programmer = "raiden_debug_spi:target=AP,custom_rst=true";
		*prepare_ctrl_name = ccd_cpu_fw_spi;
		serial_cmd = "dut-control -o ccd_serialname 2>/dev/null";
	} else if (strstr(servo_type, "c2d2")) {
		/* Most C2D2 devices don't support flashing AP, so this must
		 * come after CCD.
		 */
		VB2_DEBUG("Selected C2D2.\n");
		programmer = raiden_debug_spi;
		*prepare_ctrl_name = cpu_fw_spi;
		serial_cmd = ("dut-control -o c2d2_serialname"
			" 2>/dev/null");
	} else {
		WARN("Unknown servo: %s\nAssuming debug header.\n", servo_type);
		programmer = raiden_debug_spi;
		*prepare_ctrl_name = cpu_fw_spi;
	}

	/*
	 * To support "multiple servos connected but only one servod running" we
	 * should always try to get the serial number.
	 */
	VB2_DEBUG("Select servod by %s=%s\n", servo_id_type, servo_id);
	servo_serial = host_shell(serial_cmd);
	VB2_DEBUG("Servo SN=%s (serial cmd: %s)\n", servo_serial, serial_cmd);
	if (!(servo_serial && *servo_serial)) {
		ERROR("Failed to get serial: %s=%s\n", servo_id_type, servo_id);
		/* If there is no servo serial, undo the prepare_ctrl_name. */
		*prepare_ctrl_name = NULL;
	} else if (programmer) {
		if (!servo_serial) {
			ret = strdup(programmer);
		} else {
			const char prefix = strchr(programmer, ':') ? ',' : ':';
			ASPRINTF(&ret, "%s%cserial=%s", programmer, prefix,
				 servo_serial);
		}
		VB2_DEBUG("Servo programmer: %s\n", ret);
	}

	free(servo_type);
	free(servo_serial);

	return ret;
}
/*
 * Returns 1 if the programmers in image1 and image2 are the same.
 */
static int is_the_same_programmer(const struct firmware_image *image1,
				  const struct firmware_image *image2)
{
	assert(image1 && image2);

	/* Including if both are NULL. */
	if (image1->programmer == image2->programmer)
		return 1;

	/* Not the same if either one is NULL. */
	if (!image1->programmer || !image2->programmer)
		return 0;

	return strcmp(image1->programmer, image2->programmer) == 0;
}

int load_system_firmware(struct updater_config *cfg,
			 struct firmware_image *image)
{
	if (!strcmp(image->programmer, FLASHROM_PROGRAMMER_INTERNAL_EC)) {
		WARN("%s: flashrom support for CrOS EC is EOL.\n", __func__);
	}

	int r, i;
	const int tries = 1 + get_config_quirk(QUIRK_EXTRA_RETRIES, cfg);

	int verbose = cfg->verbosity + 1; /* libflashrom verbose 1 = WARN. */

	for (i = 1, r = -1; i <= tries && r != 0; i++, verbose++) {
		if (i > 1)
			WARN("Retry reading firmware (%d/%d)...\n", i, tries);
		INFO("Reading SPI Flash..\n");
		r = flashrom_read_image(image, NULL, 0, verbose);
	}
	if (!r)
		r = parse_firmware_image(image);
	return r;
}

/*
 * Writes sections from a given firmware image to the system firmware.
 * Regions should be NULL for writing the whole image, or a list of
 * FMAP section names (and ended with a NULL).
 * Returns 0 if success, non-zero if error.
 */
int write_system_firmware(struct updater_config *cfg,
			  const struct firmware_image *image,
			  const char * const regions[],
				const size_t regions_len)
{
	if (!strcmp(image->programmer, FLASHROM_PROGRAMMER_INTERNAL_EC)) {
		WARN("%s: flashrom support for CrOS EC is EOL.\n", __func__);
	}

	int r = 0, i;
	const int tries = 1 + get_config_quirk(QUIRK_EXTRA_RETRIES, cfg);
	struct firmware_image *flash_contents = NULL;

	if (cfg->use_diff_image && cfg->image_current.data &&
	    is_the_same_programmer(&cfg->image_current, image))
		flash_contents = &cfg->image_current;

	int verbose = cfg->verbosity + 1; /* libflashrom verbose 1 = WARN. */

	for (i = 1, r = -1; i <= tries && r != 0; i++, verbose++) {
		if (i > 1)
			WARN("Retry writing firmware (%d/%d)...\n", i, tries);
		INFO("Writing SPI Flash..\n");
		r = flashrom_write_image(image, regions, regions_len,
					 flash_contents, cfg->do_verify,
					 verbose);
		/*
		 * Force a newline to flush stdout in case if
		 * flashrom_write_image left some messages in the buffer.
		 */
		fprintf(stdout, "\n");

	}
	return r;
}

/*
 * Helper function to create a new temporary file.
 * All files created will be removed remove_all_temp_files().
 * Returns the path of new file, or NULL on failure.
 */
const char *create_temp_file(struct tempfile *head)
{
	struct tempfile *new_temp;
	char new_path[] = P_tmpdir "/fwupdater.XXXXXX";
	int fd;
	mode_t umask_save;

	/* Set the umask before mkstemp for security considerations. */
	umask_save = umask(077);
	fd = mkstemp(new_path);
	umask(umask_save);
	if (fd < 0) {
		ERROR("Failed to create new temp file in %s\n", new_path);
		return NULL;
	}
	close(fd);
	new_temp = (struct tempfile *)malloc(sizeof(*new_temp));
	if (new_temp)
		new_temp->filepath = strdup(new_path);
	if (!new_temp || !new_temp->filepath) {
		remove(new_path);
		free(new_temp);
		ERROR("Failed to allocate buffer for new temp file.\n");
		return NULL;
	}
	VB2_DEBUG("Created new temporary file: %s.\n", new_path);
	new_temp->next = NULL;
	while (head->next)
		head = head->next;
	head->next = new_temp;
	return new_temp->filepath;
}

/*
 * Helper function to remove all files created by create_temp_file().
 * This is intended to be called only once at end of program execution.
 */
void remove_all_temp_files(struct tempfile *head)
{
	/* head itself is dummy and should not be removed. */
	assert(!head->filepath);
	struct tempfile *next = head->next;
	head->next = NULL;
	while (next) {
		head = next;
		next = head->next;
		assert(head->filepath);
		VB2_DEBUG("Remove temporary file: %s.\n", head->filepath);
		remove(head->filepath);
		free(head->filepath);
		free(head);
	}
}

/*
 * Returns rootkey hash of firmware image, or NULL on failure.
 */
const char *get_firmware_rootkey_hash(const struct firmware_image *image)
{
	const struct vb2_gbb_header *gbb = NULL;
	const struct vb2_packed_key *rootkey = NULL;

	assert(image->data);

	gbb = find_gbb(image);
	if (!gbb) {
		WARN("No GBB found in image.\n");
		return NULL;
	}

	rootkey = get_rootkey(gbb);
	if (!rootkey) {
		WARN("No rootkey found in image.\n");
		return NULL;
	}

	return packed_key_sha1_string(rootkey);
}

/*
 * Overwrite the given offset of a section in the firmware image with the
 * given values.
 * Returns 0 on success, otherwise failure.
 */
int overwrite_section(struct firmware_image *image,
			     const char *fmap_section, size_t offset,
			     size_t size, const uint8_t *new_values)
{
	struct firmware_section section;

	find_firmware_section(&section, image, fmap_section);
	if (section.size < offset + size) {
		ERROR("Section smaller than given offset + size\n");
		return -1;
	}

	if (memcmp(section.data + offset, new_values, size) == 0) {
		VB2_DEBUG("Section already contains given values.\n");
		return 0;
	}

	memcpy(section.data + offset, new_values, size);
	return 0;
}
