Exemple #1
0
/* TODO: how should we properly handle compute_hash() failures? */
int compute_hash(struct file *file, char *filename)
{
	int ret;
	char key[SWUPD_HASH_LEN];
	size_t key_len;
	unsigned char *blob;
	FILE *fl;

	if (file->is_deleted) {
		hash_set_zeros(file->hash);
		return 0;
	}

	hash_set_zeros(key);

	if (file->is_link) {
		char link[PATH_MAXLEN];
		memset(link, 0, PATH_MAXLEN);

		ret = readlink(filename, link, PATH_MAXLEN - 1);

		if (ret >= 0) {
			hmac_compute_key(filename, &file->stat, key, &key_len, file->use_xattrs);
			hmac_sha256_for_string(file->hash,
					       (const unsigned char *)key,
					       key_len,
					       link);
			return 0;
		} else {
			return -1;
		}
	}

	if (file->is_dir) {
		hmac_compute_key(filename, &file->stat, key, &key_len, file->use_xattrs);
		hmac_sha256_for_string(file->hash,
				       (const unsigned char *)key,
				       key_len,
				       SWUPD_HASH_DIRNAME); //Make independent of dirname
		return 0;
	}

	/* if we get here, this is a regular file */
	fl = fopen(filename, "r");
	if (!fl) {
		return -1;
	}
	blob = mmap(NULL, file->stat.st_size, PROT_READ, MAP_PRIVATE, fileno(fl), 0);
	if (blob == MAP_FAILED && file->stat.st_size != 0) {
		abort();
	}

	hmac_compute_key(filename, &file->stat, key, &key_len, file->use_xattrs);
	hmac_sha256_for_data(file->hash,
			     (const unsigned char *)key,
			     key_len,
			     blob,
			     file->stat.st_size);
	munmap(blob, file->stat.st_size);
	fclose(fl);
	return 0;
}
Exemple #2
0
/* this function MUST be kept in sync with the server
 * return is NULL if there was an error. If the file does not exist,
 * a "0000000..." hash is returned as is our convention in the manifest
 * for deleted files */
char *compute_hash(struct file *file, char *filename)
{
	struct stat stat;
	int ret;
	unsigned char *blob;
	char *key = NULL;
	size_t key_len;
	FILE *fl;
	struct update_stat tfstat;
	char *hash = NULL;

	memset(&stat, 0, sizeof(stat));
	memset(&tfstat, 0, sizeof(tfstat));
	ret = lstat(filename, &stat);
	if (ret < 0) {
		if (errno == ENOENT) {
			LOG_DEBUG(NULL, "File does not exist, mark as deleted", class_file_misc, "%s", filename);
			file->is_deleted = 1;
			hash = strdup("0000000000000000000000000000000000000000000000000000000000000000");
			if (!hash)
				abort();
			return hash;
		}

		LOG_ERROR(NULL, "stat error ", class_file_io, "\\*filename=\"%s\",strerror=\"%s\"*\\",
				filename, strerror(errno));
		return NULL;
	}
	tfstat.st_mode = stat.st_mode;
	tfstat.st_uid = stat.st_uid;
	tfstat.st_gid = stat.st_gid;
	tfstat.st_rdev = stat.st_rdev;
	tfstat.st_size = stat.st_size;
	/* just server does this:
	file->size = stat.st_size;
	 */
	if ((file->is_link) || (S_ISLNK(stat.st_mode))) {
		char link[PATH_MAXLEN];
		memset(link, 0, PATH_MAXLEN);

		file->is_file = 0;
		file->is_dir = 0;
		file->is_link = 1;

		ret = readlink(filename, link, PATH_MAXLEN - 1);

		memset(&tfstat.st_mode, 0, sizeof(tfstat.st_mode));

		if (ret >= 0) {
			hmac_compute_key(filename, &tfstat, &key, &key_len, file->use_xattrs);
			hash = hmac_sha256_for_string(
					(const unsigned char *)key,
					key_len,
					link);
			if (!hash)
				abort();
			free(key);
			return hash;
		} else {
			LOG_ERROR(NULL, "readlink error ", class_file_io, "\\*ret=\"%i\",errno=\"%i\",strerror=\"%s\"*\\",
					ret, errno, strerror(errno));
			return NULL;
		}
	}

	if ((file->is_dir) || (S_ISDIR(stat.st_mode))) {
		file->is_file = 0;
		file->is_dir = 1;
		file->is_link = 0;

		tfstat.st_size = 0;

		hmac_compute_key(filename, &tfstat, &key, &key_len, file->use_xattrs);
		hash = hmac_sha256_for_string(
					(const unsigned char *)key,
					key_len,
					file->filename);	//file->filename not filename
		if (!hash)
			abort();
		free(key);
		return hash;
	}

	/* if we get here, this is a regular file */
	file->is_file = 1;
	file->is_dir = 0;
	file->is_link = 0;

	fl = fopen(filename, "r");
	if (!fl) {
		LOG_ERROR(NULL, "file open error ", class_file_io, "\\*filename=\"%s\",strerror=\"%s\"*\\",
				filename, strerror(errno));
		return NULL;
	}
	blob = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fileno(fl), 0);
	if (blob == MAP_FAILED && stat.st_size != 0)
		abort();

	hmac_compute_key(filename, &tfstat, &key, &key_len, file->use_xattrs);
	hash = hmac_sha256_for_data(
				(const unsigned char *)key,
				key_len,
				blob,
				stat.st_size);
	munmap(blob, stat.st_size);
	fclose(fl);
	if (!hash)
		abort();
	free(key);
	return hash;
}