Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Fix digest handling after 5ae680e49
Bryan Drewery committed 12 years ago
commit 7879c713acbb9b14c8633268761d75d13027ac8c
parent c7b051f
4 files changed +59 -24
modified libpkg/private/utils.h
@@ -84,13 +84,14 @@ int is_dir(const char *);
int is_conf_file(const char *path, char *newpath, size_t len);

int sha256_file(const char *, char[SHA256_DIGEST_LENGTH * 2 +1]);
+
int sha256_fd(int fd, char[SHA256_DIGEST_LENGTH * 2 +1]);
int md5_file(const char *, char[MD5_DIGEST_LENGTH * 2 +1]);

int rsa_new(struct rsa_key **, pem_password_cb *, char *path);
void rsa_free(struct rsa_key *);
int rsa_sign(char *path, struct rsa_key *rsa, unsigned char **sigret, unsigned int *siglen);
int rsa_verify(const char *path, const char *key,
-
		unsigned char *sig, unsigned int sig_len);
+
		unsigned char *sig, unsigned int sig_len, int fd);

bool is_hardlink(struct hardlinks *hl, struct stat *st);

modified libpkg/rsa.c
@@ -82,14 +82,17 @@ _load_rsa_public_key(const char *rsa_key_path)

int
rsa_verify(const char *path, const char *key, unsigned char *sig,
-
    unsigned int sig_len)
+
    unsigned int sig_len, int fd)
{
	char sha256[SHA256_DIGEST_LENGTH *2 +1];
	char errbuf[1024];
	RSA *rsa = NULL;
	int ret;

-
	sha256_file(path, sha256);
+
	if (fd != -1)
+
		sha256_fd(fd, sha256);
+
	else
+
		sha256_file(path, sha256);

	SSL_load_error_strings();
	OpenSSL_add_all_algorithms();
modified libpkg/update.c
@@ -122,7 +122,7 @@ repo_archive_extract_file(int fd, const char *file, const char *dest, const char

	while (archive_read_next_header(a, &ae) == ARCHIVE_OK) {
		if (strcmp(archive_entry_pathname(ae), file) == 0) {
-
			if (dest != NULL) {
+
			if (dest_fd == -1) {
				archive_entry_set_pathname(ae, dest);
				/*
				 * The repo should be owned by root and not writable
@@ -136,8 +136,7 @@ repo_archive_extract_file(int fd, const char *file, const char *dest, const char
					rc = EPKG_FATAL;
					goto cleanup;
				}
-
			}
-
			if (dest_fd != -1) {
+
			} else {
				if (archive_read_data_into_fd(a, dest_fd) != 0) {
					pkg_emit_errno("archive_read_extract", "extract error");
					rc = EPKG_FATAL;
@@ -156,11 +155,12 @@ repo_archive_extract_file(int fd, const char *file, const char *dest, const char
	if (repokey != NULL) {
		if (sig != NULL) {
			ret = rsa_verify(dest, repokey,
-
					sig, siglen - 1);
+
					sig, siglen - 1, dest_fd);
			if (ret != EPKG_OK) {
				pkg_emit_error("Invalid signature, "
						"removing repository.");
-
				unlink(dest);
+
				if (dest != NULL)
+
					unlink(dest);
				free(sig);
				rc = EPKG_FATAL;
				goto cleanup;
@@ -170,7 +170,8 @@ repo_archive_extract_file(int fd, const char *file, const char *dest, const char
			pkg_emit_error("No signature found in the repository.  "
					"Can not validate against %s key.", repokey);
			rc = EPKG_FATAL;
-
			unlink(dest);
+
			if (dest != NULL)
+
				unlink(dest);
			goto cleanup;
		}
	}
@@ -190,7 +191,6 @@ repo_fetch_remote_extract_tmp(struct pkg_repo *repo, const char *filename,
	FILE *res = NULL;
	const char *tmpdir;
	char tmp[MAXPATHLEN];
-
	char tmp_rsa[MAXPATHLEN];

	fd = repo_fetch_remote_tmp(repo, filename, extension, t, rc);
	if (fd == -1) {
@@ -205,7 +205,6 @@ repo_fetch_remote_extract_tmp(struct pkg_repo *repo, const char *filename,
	mask = umask(022);
	dest_fd = mkstemp(tmp);
	umask(mask);
-
	snprintf(tmp_rsa, MAXPATHLEN, "%s.rsa", tmp);
	if (dest_fd == -1) {
		pkg_emit_error("Could not create temporary file %s, "
				"aborting update.\n", tmp);
@@ -213,12 +212,10 @@ repo_fetch_remote_extract_tmp(struct pkg_repo *repo, const char *filename,
		goto cleanup;
	}
	(void)unlink(tmp);
-
	if (repo_archive_extract_file(fd, archive_file, tmp_rsa, repo->pubkey, dest_fd) != EPKG_OK) {
+
	if (repo_archive_extract_file(fd, archive_file, NULL, repo->pubkey, dest_fd) != EPKG_OK) {
		*rc = EPKG_FATAL;
-
		(void)unlink(tmp_rsa);
		goto cleanup;
	}
-
	(void)unlink(tmp_rsa);

	res = fdopen(dest_fd, "r");
	if (res == NULL) {
modified libpkg/utils.c
@@ -334,15 +334,45 @@ sha256_hash(unsigned char hash[SHA256_DIGEST_LENGTH],
int
sha256_file(const char *path, char out[SHA256_DIGEST_LENGTH * 2 + 1])
{
-
	FILE *fp;
+
	int fd;
+
	int ret;
+

+
	if ((fd = open(path, O_RDONLY)) == -1) {
+
		pkg_emit_errno("fopen", path);
+
		return (EPKG_FATAL);
+
	}
+

+
	ret = sha256_fd(fd, out);
+

+
	close(fd);
+

+
	return (ret);
+
}
+

+
int
+
sha256_fd(int fd, char out[SHA256_DIGEST_LENGTH * 2 + 1])
+
{
+
	int my_fd = -1;
+
	FILE *fp = NULL;
	char buffer[BUFSIZ];
	unsigned char hash[SHA256_DIGEST_LENGTH];
	size_t r = 0;
+
	int ret = EPKG_OK;
	SHA256_CTX sha256;

-
	if ((fp = fopen(path, "rb")) == NULL) {
-
		pkg_emit_errno("fopen", path);
-
		return EPKG_FATAL;
+
	out[0] = '\0';
+

+
	/* Duplicate the fd so that fclose(3) does not close it. */
+
	if ((my_fd = dup(fd)) == -1) {
+
		pkg_emit_errno("dup", "");
+
		ret = EPKG_FATAL;
+
		goto cleanup;
+
	}
+

+
	if ((fp = fdopen(my_fd, "rb")) == NULL) {
+
		pkg_emit_errno("fdopen", "");
+
		ret = EPKG_FATAL;
+
		goto cleanup;
	}

	SHA256_Init(&sha256);
@@ -351,16 +381,20 @@ sha256_file(const char *path, char out[SHA256_DIGEST_LENGTH * 2 + 1])
		SHA256_Update(&sha256, buffer, r);

	if (ferror(fp) != 0) {
-
		fclose(fp);
-
		out[0] = '\0';
-
		pkg_emit_errno("fread", path);
-
		return EPKG_FATAL;
+
		pkg_emit_errno("fread", "");
+
		ret = EPKG_FATAL;
+
		goto cleanup;
	}

-
	fclose(fp);
-

	SHA256_Final(hash, &sha256);
	sha256_hash(hash, out);
+
cleanup:
+

+
	if (fp != NULL)
+
		fclose(fp);
+
	else if (my_fd != -1)
+
		close(my_fd);
+
	(void)lseek(fd, 0, SEEK_SET);

	return (EPKG_OK);
}