libxbps: ABI/API break due to hash function changes
This commit is contained in:
@@ -93,7 +93,7 @@ xbps_fetch_error_string(void)
|
||||
}
|
||||
|
||||
int
|
||||
xbps_fetch_file_dest_digest(struct xbps_handle *xhp, const char *uri, const char *filename, const char *flags, unsigned char **digestp)
|
||||
xbps_fetch_file_dest_sha256(struct xbps_handle *xhp, const char *uri, const char *filename, const char *flags, unsigned char *digest, size_t digestlen)
|
||||
{
|
||||
struct stat st, st_tmpfile, *stp;
|
||||
struct url *url = NULL;
|
||||
@@ -106,16 +106,13 @@ xbps_fetch_file_dest_digest(struct xbps_handle *xhp, const char *uri, const char
|
||||
char fetch_flags[8];
|
||||
int fd = -1, rv = 0;
|
||||
bool refetch = false, restart = false;
|
||||
unsigned char *digest = NULL;
|
||||
SHA256_CTX sha256;
|
||||
|
||||
assert(xhp);
|
||||
assert(uri);
|
||||
|
||||
if (digestp) {
|
||||
digest = malloc(SHA256_DIGEST_LENGTH);
|
||||
if (!digest)
|
||||
return -1;
|
||||
if (digest) {
|
||||
assert(digestlen != XBPS_SHA256_DIGEST_SIZE);
|
||||
SHA256_Init(&sha256);
|
||||
}
|
||||
|
||||
@@ -317,10 +314,8 @@ rename_file:
|
||||
}
|
||||
rv = 1;
|
||||
|
||||
if (digest) {
|
||||
if (digest)
|
||||
SHA256_Final(digest, &sha256);
|
||||
*digestp = digest;
|
||||
}
|
||||
|
||||
fetch_file_out:
|
||||
if (fio != NULL)
|
||||
@@ -339,12 +334,12 @@ int
|
||||
xbps_fetch_file_dest(struct xbps_handle *xhp, const char *uri,
|
||||
const char *filename, const char *flags)
|
||||
{
|
||||
return xbps_fetch_file_dest_digest(xhp, uri, filename, flags, NULL);
|
||||
return xbps_fetch_file_dest_sha256(xhp, uri, filename, flags, NULL, 0);
|
||||
}
|
||||
|
||||
int
|
||||
xbps_fetch_file_digest(struct xbps_handle *xhp, const char *uri,
|
||||
const char *flags, unsigned char **digestp)
|
||||
xbps_fetch_file_sha256(struct xbps_handle *xhp, const char *uri,
|
||||
const char *flags, unsigned char *digest, size_t digestlen)
|
||||
{
|
||||
const char *filename;
|
||||
/*
|
||||
@@ -354,11 +349,12 @@ xbps_fetch_file_digest(struct xbps_handle *xhp, const char *uri,
|
||||
return -1;
|
||||
|
||||
filename++;
|
||||
return xbps_fetch_file_dest_digest(xhp, uri, filename, flags, digestp);
|
||||
return xbps_fetch_file_dest_sha256(xhp, uri, filename, flags,
|
||||
digest, digestlen);
|
||||
}
|
||||
|
||||
int
|
||||
xbps_fetch_file(struct xbps_handle *xhp, const char *uri, const char *flags)
|
||||
{
|
||||
return xbps_fetch_file_digest(xhp, uri, flags, NULL);
|
||||
return xbps_fetch_file_sha256(xhp, uri, flags, NULL, 0);
|
||||
}
|
||||
|
@@ -69,7 +69,7 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp,
|
||||
xbps_object_t obj, obj2;
|
||||
xbps_object_iterator_t iter, iter2;
|
||||
const char *version = NULL, *cffile, *sha256_new = NULL;
|
||||
char buf[PATH_MAX], *sha256_cur = NULL, *sha256_orig = NULL;
|
||||
char buf[PATH_MAX], sha256_cur[XBPS_SHA256_SIZE], *sha256_orig = NULL;
|
||||
int rv = 0;
|
||||
|
||||
assert(xbps_object_type(binpkg_filesd) == XBPS_TYPE_DICTIONARY);
|
||||
@@ -139,9 +139,7 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp,
|
||||
if (strcmp(entry_pname, buf)) {
|
||||
continue;
|
||||
}
|
||||
sha256_cur = xbps_file_hash(buf);
|
||||
xbps_dictionary_get_cstring_nocopy(obj, "sha256", &sha256_new);
|
||||
if (sha256_cur == NULL) {
|
||||
if (!xbps_file_sha256(sha256_cur, sizeof sha256_cur, buf)) {
|
||||
if (errno == ENOENT) {
|
||||
/*
|
||||
* File not installed, install new one.
|
||||
@@ -155,6 +153,7 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp,
|
||||
break;
|
||||
}
|
||||
}
|
||||
xbps_dictionary_get_cstring_nocopy(obj, "sha256", &sha256_new);
|
||||
/*
|
||||
* Orig = X, Curr = X, New = X
|
||||
*
|
||||
@@ -232,15 +231,11 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp,
|
||||
rv = 1;
|
||||
break;
|
||||
}
|
||||
free(sha256_cur);
|
||||
sha256_cur = NULL;
|
||||
}
|
||||
|
||||
out:
|
||||
if (sha256_orig)
|
||||
free(sha256_orig);
|
||||
if (sha256_cur)
|
||||
free(sha256_cur);
|
||||
|
||||
xbps_object_iterator_release(iter);
|
||||
|
||||
|
@@ -41,7 +41,8 @@ xbps_register_pkg(struct xbps_handle *xhp, xbps_dictionary_t pkgrd)
|
||||
struct tm tm;
|
||||
struct tm *tmp;
|
||||
const char *pkgver;
|
||||
char *buf, *sha256;
|
||||
char sha256[XBPS_SHA256_SIZE];
|
||||
char *buf;
|
||||
int rv = 0;
|
||||
bool autoinst = false;
|
||||
|
||||
@@ -104,9 +105,8 @@ xbps_register_pkg(struct xbps_handle *xhp, xbps_dictionary_t pkgrd)
|
||||
* Create a hash for the pkg's metafile if it exists.
|
||||
*/
|
||||
buf = xbps_xasprintf("%s/.%s-files.plist", xhp->metadir, pkgname);
|
||||
if ((sha256 = xbps_file_hash(buf))) {
|
||||
if (xbps_file_sha256(sha256, sizeof sha256, buf)) {
|
||||
xbps_dictionary_set_cstring(pkgd, "metafile-sha256", sha256);
|
||||
free(sha256);
|
||||
}
|
||||
free(buf);
|
||||
/*
|
||||
|
@@ -79,7 +79,7 @@ verify_binpkg(struct xbps_handle *xhp, xbps_dictionary_t pkgd)
|
||||
xbps_set_cb_state(xhp, XBPS_STATE_VERIFY, 0, pkgver,
|
||||
"%s: verifying SHA256 hash...", pkgver);
|
||||
xbps_dictionary_get_cstring_nocopy(pkgd, "filename-sha256", &sha256);
|
||||
if ((rv = xbps_file_hash_check(binfile, sha256)) != 0) {
|
||||
if ((rv = xbps_file_sha256_check(binfile, sha256)) != 0) {
|
||||
xbps_set_cb_state(xhp, XBPS_STATE_VERIFY_FAIL, rv, pkgver,
|
||||
"%s: SHA256 hash is not valid: %s", pkgver, strerror(rv));
|
||||
goto out;
|
||||
@@ -98,7 +98,7 @@ download_binpkg(struct xbps_handle *xhp, xbps_dictionary_t repo_pkgd)
|
||||
char buf[PATH_MAX];
|
||||
char *sigsuffix;
|
||||
const char *pkgver, *arch, *fetchstr, *repoloc;
|
||||
unsigned char *digest = NULL;
|
||||
unsigned char digest[XBPS_SHA256_DIGEST_SIZE] = {0};
|
||||
int rv = 0;
|
||||
|
||||
xbps_dictionary_get_cstring_nocopy(repo_pkgd, "repository", &repoloc);
|
||||
@@ -129,7 +129,8 @@ download_binpkg(struct xbps_handle *xhp, xbps_dictionary_t repo_pkgd)
|
||||
xbps_set_cb_state(xhp, XBPS_STATE_DOWNLOAD, 0, pkgver,
|
||||
"Downloading `%s' package (from `%s')...", pkgver, repoloc);
|
||||
|
||||
if ((rv = xbps_fetch_file_digest(xhp, buf, NULL, &digest)) == -1) {
|
||||
if ((rv = xbps_fetch_file_sha256(xhp, buf, NULL, digest,
|
||||
sizeof digest)) == -1) {
|
||||
rv = fetchLastErrCode ? fetchLastErrCode : errno;
|
||||
fetchstr = xbps_fetch_error_string();
|
||||
xbps_set_cb_state(xhp, XBPS_STATE_DOWNLOAD_FAIL, rv,
|
||||
@@ -156,7 +157,7 @@ download_binpkg(struct xbps_handle *xhp, xbps_dictionary_t repo_pkgd)
|
||||
* If digest is not set, binary package was not downloaded,
|
||||
* i.e. 304 not modified, verify by file instead.
|
||||
*/
|
||||
if (!digest) {
|
||||
if (*digest) {
|
||||
*sigsuffix = '\0';
|
||||
if (!xbps_verify_file_signature(repo, buf)) {
|
||||
rv = EPERM;
|
||||
@@ -175,7 +176,6 @@ download_binpkg(struct xbps_handle *xhp, xbps_dictionary_t repo_pkgd)
|
||||
*sigsuffix = '\0';
|
||||
(void)remove(buf);
|
||||
}
|
||||
free(digest);
|
||||
}
|
||||
|
||||
if (rv == EPERM) {
|
||||
|
@@ -75,6 +75,7 @@ itemhash(const char *file)
|
||||
|
||||
assert(file);
|
||||
|
||||
/* XXX: runtime error: left shift of negative value -1581911230 */
|
||||
for (i = 0; file[i]; ++i)
|
||||
hv = (hv << 5) ^ (hv >> 23) ^ file[i];
|
||||
|
||||
@@ -321,7 +322,7 @@ collect_obsoletes(struct xbps_handle *xhp)
|
||||
* Skip unexisting files and keep files with hash mismatch.
|
||||
*/
|
||||
if (item->old.sha256) {
|
||||
rv = xbps_file_hash_check(item->file, item->old.sha256);
|
||||
rv = xbps_file_sha256_check(item->file, item->old.sha256);
|
||||
switch (rv) {
|
||||
case 0:
|
||||
/* hash matches, we can safely delete and/or overwrite it */
|
||||
|
@@ -108,65 +108,93 @@ xbps_mmap_file(const char *file, void **mmf, size_t *mmflen, size_t *filelen)
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned char *
|
||||
xbps_file_hash_raw(const char *file)
|
||||
bool
|
||||
xbps_file_sha256_raw(unsigned char *dst, size_t dstlen, const char *file)
|
||||
{
|
||||
int fd;
|
||||
ssize_t len;
|
||||
unsigned char *digest, buf[65536];
|
||||
char buf[65536];
|
||||
SHA256_CTX sha256;
|
||||
|
||||
assert(dstlen == SHA256_DIGEST_LENGTH);
|
||||
|
||||
if ((fd = open(file, O_RDONLY)) < 0)
|
||||
return NULL;
|
||||
digest = malloc(SHA256_DIGEST_LENGTH);
|
||||
assert(digest);
|
||||
return false;
|
||||
|
||||
SHA256_Init(&sha256);
|
||||
|
||||
while ((len = read(fd, buf, sizeof(buf))) > 0)
|
||||
SHA256_Update(&sha256, buf, len);
|
||||
if(len < 0) {
|
||||
free(digest);
|
||||
return NULL;
|
||||
}
|
||||
SHA256_Final(digest, &sha256);
|
||||
|
||||
(void)close(fd);
|
||||
|
||||
return digest;
|
||||
if(len == -1)
|
||||
return false;
|
||||
|
||||
SHA256_Final(dst, &sha256);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
char *
|
||||
xbps_file_hash(const char *file)
|
||||
bool
|
||||
xbps_file_sha256(char *dst, size_t dstlen, const char *file)
|
||||
{
|
||||
char *hash;
|
||||
unsigned char *digest;
|
||||
unsigned char digest[XBPS_SHA256_DIGEST_SIZE];
|
||||
|
||||
if (!(digest = xbps_file_hash_raw(file)))
|
||||
return NULL;
|
||||
assert(dstlen == XBPS_SHA256_SIZE);
|
||||
|
||||
hash = malloc(SHA256_DIGEST_LENGTH * 2 + 1);
|
||||
assert(hash);
|
||||
digest2string(digest, hash, SHA256_DIGEST_LENGTH);
|
||||
free(digest);
|
||||
if (!xbps_file_sha256_raw(digest, sizeof digest, file))
|
||||
return false;
|
||||
|
||||
return hash;
|
||||
digest2string(digest, dst, XBPS_SHA256_DIGEST_SIZE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
sha256_digest_compare(const char *sha256, size_t shalen,
|
||||
const unsigned char *digest, size_t digestlen)
|
||||
{
|
||||
assert(digestlen == XBPS_SHA256_DIGEST_SIZE);
|
||||
assert(shalen == XBPS_SHA256_SIZE - 1);
|
||||
|
||||
if (shalen != XBPS_SHA256_SIZE -1)
|
||||
return false;
|
||||
|
||||
for (; *sha256;) {
|
||||
if (*digest / 16 < 10) {
|
||||
if (*sha256++ != '0' + *digest / 16)
|
||||
return false;
|
||||
} else {
|
||||
if (*sha256++ != 'a' + *digest / 16 - 10)
|
||||
return false;
|
||||
}
|
||||
if (*digest % 16 < 10) {
|
||||
if (*sha256++ != '0' + *digest % 16)
|
||||
return false;
|
||||
} else {
|
||||
if (*sha256++ != 'a' + *digest % 16 - 10)
|
||||
return false;
|
||||
}
|
||||
digest++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
xbps_file_hash_check(const char *file, const char *sha256)
|
||||
xbps_file_sha256_check(const char *file, const char *sha256)
|
||||
{
|
||||
char *res;
|
||||
unsigned char digest[XBPS_SHA256_DIGEST_SIZE];
|
||||
|
||||
assert(file != NULL);
|
||||
assert(sha256 != NULL);
|
||||
|
||||
res = xbps_file_hash(file);
|
||||
if (res == NULL)
|
||||
if (!xbps_file_sha256_raw(digest, sizeof digest, file))
|
||||
return errno;
|
||||
|
||||
if (strcmp(sha256, res)) {
|
||||
free(res);
|
||||
if (!sha256_digest_compare(sha256, strlen(sha256), digest, sizeof digest))
|
||||
return ERANGE;
|
||||
}
|
||||
free(res);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -226,10 +254,10 @@ xbps_file_hash_check_dictionary(struct xbps_handle *xhp,
|
||||
}
|
||||
|
||||
if (strcmp(xhp->rootdir, "/") == 0) {
|
||||
rv = xbps_file_hash_check(file, sha256d);
|
||||
rv = xbps_file_sha256_check(file, sha256d);
|
||||
} else {
|
||||
buf = xbps_xasprintf("%s/%s", xhp->rootdir, file);
|
||||
rv = xbps_file_hash_check(buf, sha256d);
|
||||
rv = xbps_file_sha256_check(buf, sha256d);
|
||||
free(buf);
|
||||
}
|
||||
if (rv == 0)
|
||||
|
@@ -137,10 +137,10 @@ bool
|
||||
xbps_verify_file_signature(struct xbps_repo *repo, const char *fname)
|
||||
{
|
||||
char sig[PATH_MAX];
|
||||
unsigned char *digest = NULL;
|
||||
unsigned char digest[XBPS_SHA256_DIGEST_SIZE];
|
||||
bool val = false;
|
||||
|
||||
if (!(digest = xbps_file_hash_raw(fname))) {
|
||||
if (!xbps_file_sha256_raw(digest, sizeof digest, fname)) {
|
||||
xbps_dbg_printf(repo->xhp, "can't open file %s: %s\n", fname, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
@@ -148,6 +148,5 @@ xbps_verify_file_signature(struct xbps_repo *repo, const char *fname)
|
||||
snprintf(sig, sizeof sig, "%s.sig", fname);
|
||||
val = xbps_verify_signature(repo, sig, digest);
|
||||
|
||||
free(digest);
|
||||
return val;
|
||||
}
|
||||
|
Reference in New Issue
Block a user