Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Add new pkg_checksum_validate_fileat and use it
Baptiste Daroussin committed 10 years ago
commit aa950e31c5c92d292aa660a947692030b1aeb423
parent 11d7345
3 files changed +44 -25
modified libpkg/pkg_checksum.c
@@ -788,6 +788,44 @@ pkg_checksum_generate_file(const char *path, pkg_checksum_type_t type)
	return (cksum);
}

+
bool
+
pkg_checksum_validate_fileat(int rootfd, const char *path, const char *sum)
+
{
+
	struct stat st;
+
	char *newsum;
+
	pkg_checksum_type_t type;
+

+
	type = pkg_checksum_file_get_type(sum, strlen(sum));
+
	if (type == PKG_HASH_TYPE_UNKNOWN) {
+
		type = PKG_HASH_TYPE_SHA256_HEX;
+
	} else {
+
		sum = strchr(sum, PKG_CKSUM_SEPARATOR);
+
		sum++;
+
	}
+

+
	if (fstatat(rootfd, path, &st, AT_SYMLINK_NOFOLLOW) == -1) {
+
		pkg_emit_errno("pkg_checksum_validate_file", "lstat");
+
		return (false);
+
	}
+

+
	if (S_ISLNK(st.st_mode))
+
		newsum = pkg_checksum_symlinkat(rootfd, path, NULL, type);
+
	else
+
		newsum = pkg_checksum_fileat(rootfd, path, type);
+

+
	if (newsum == NULL)
+
		return (false);
+

+
	if (strcmp(sum, newsum) != 0) {
+
		free(newsum);
+
		return (false);
+
	}
+

+
	free(newsum);
+

+
	return (true);
+
}
+

char *
pkg_checksum_generate_fileat(int rootfd, const char *path,
    pkg_checksum_type_t type)
modified libpkg/pkg_delete.c
@@ -277,35 +277,15 @@ pkg_delete_file(struct pkg *pkg, struct pkg_file *file, unsigned force)
		len--;

	/* Regular files and links */
-
	/* check sha256 */
+
	/* check checksum */
	if (!force && file->sum != NULL) {
-
		if (fstatat(pkg->rootfd, path, &st, AT_SYMLINK_NOFOLLOW) == -1) {
-
			pkg_emit_error("cannot stat %s%s%s: %s", pkg->rootpath,
+
		if (!pkg_checksum_validate_fileat(pkg->rootfd, path, file->sum)) {
+
			pkg_emit_error("%s%s%s different from original "
+
			    "checksum, not removing", pkg->rootpath,
			    pkg->rootpath[strlen(pkg->rootpath) - 1] == '/' ? "" : "/",
-
			    path, strerror(errno));
+
			    path);
			return;
		}
-
		if (S_ISLNK(st.st_mode)) {
-
			sha256 = pkg_checksum_symlinkat(pkg->rootfd, path, NULL,
-
			    PKG_HASH_TYPE_SHA256_HEX);
-
			if (!sha256)
-
				return;
-
		}
-
		else {
-
			sha256 = pkg_checksum_fileat(pkg->rootfd, path,
-
			    PKG_HASH_TYPE_SHA256_HEX);
-
			if (!sha256)
-
				return;
-
		}
-
		if (strcmp(sha256, file->sum)) {
-
			pkg_emit_error("%s%s%s fails original SHA256 "
-
				"checksum, not removing", pkg->rootpath,
-
				pkg->rootpath[strlen(pkg->rootpath) - 1] == '/' ? "" : "/",
-
				path);
-
			free(sha256);
-
			return;
-
		}
-
		free(sha256);
	}

#ifdef HAVE_CHFLAGS
modified libpkg/private/pkg.h
@@ -639,6 +639,7 @@ unsigned char *pkg_checksum_symlink(const char *path, const char *root,
unsigned char *pkg_checksum_symlinkat(int fd, const char *path,
    const char *root, pkg_checksum_type_t type);
bool pkg_checksum_validate_file(const char *path, const  char *sum);
+
bool pkg_checksum_validate_fileat(int fd, const char *path, const  char *sum);

bool pkg_checksum_is_valid(const char *cksum, size_t clen);
pkg_checksum_type_t pkg_checksum_get_type(const char *cksum, size_t clen);