[pacman-dev] [PATCH 1/3 v2] Add information on how an installed package was validated
When installing a package, store information on which validation method was used and output this on "pacman -Qi" operations. e.g. Validated By : SHA256 Sum Possible values are Unknown, None, MD5 Sum, SHA256 Sum, Signature. Signed-off-by: Allan McRae <allan@archlinux.org> --- Changed alpm_pkgvalidation_t to a bitmask lib/libalpm/alpm.h | 15 +++++++++++++++ lib/libalpm/be_local.c | 43 +++++++++++++++++++++++++++++++++++++++++++ lib/libalpm/be_package.c | 17 +++++++++++++++++ lib/libalpm/package.c | 9 +++++++++ lib/libalpm/package.h | 2 ++ lib/libalpm/sync.c | 2 ++ src/pacman/package.c | 25 +++++++++++++++++++++++++ 7 files changed, 113 insertions(+), 0 deletions(-) diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 1b3f6d7..1d77c97 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -64,6 +64,15 @@ typedef enum _alpm_pkgfrom_t { PKG_FROM_SYNCDB } alpm_pkgfrom_t; +/** Location a package object was loaded from. */ +typedef enum _alpm_pkgvalidation_t { + ALPM_PKG_VALIDATION_UNKNOWN, + ALPM_PKG_VALIDATION_NONE = (1 << 0), + ALPM_PKG_VALIDATION_MD5SUM = (1 << 1), + ALPM_PKG_VALIDATION_SHA256SUM = (1 << 2), + ALPM_PKG_VALIDATION_SIGNATURE = (1 << 3) +} alpm_pkgvalidation_t; + /** Types of version constraints in dependency specs. */ typedef enum _alpm_depmod_t { /** No version constraint */ @@ -888,6 +897,12 @@ alpm_db_t *alpm_pkg_get_db(alpm_pkg_t *pkg); */ const char *alpm_pkg_get_base64_sig(alpm_pkg_t *pkg); +/** Returns the method used to validate a package during install. + * @param pkg a pointer to package + * @return an enum member giving the validation method + */ +alpm_pkgvalidation_t alpm_pkg_get_validation(alpm_pkg_t *pkg); + /* End of alpm_pkg_t accessors */ /* @} */ diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c index 9a8c0ec..3b34a62 100644 --- a/lib/libalpm/be_local.c +++ b/lib/libalpm/be_local.c @@ -102,6 +102,12 @@ static alpm_pkgreason_t _cache_get_reason(alpm_pkg_t *pkg) return pkg->reason; } +static alpm_pkgvalidation_t _cache_get_validation(alpm_pkg_t *pkg) +{ + LAZY_LOAD(INFRQ_DESC, -1); + return pkg->validation; +} + static alpm_list_t *_cache_get_licenses(alpm_pkg_t *pkg) { LAZY_LOAD(INFRQ_DESC, NULL); @@ -223,6 +229,7 @@ static struct pkg_operations local_pkg_ops = { .get_arch = _cache_get_arch, .get_isize = _cache_get_isize, .get_reason = _cache_get_reason, + .get_validation = _cache_get_validation, .has_scriptlet = _cache_has_scriptlet, .get_licenses = _cache_get_licenses, .get_groups = _cache_get_groups, @@ -603,6 +610,26 @@ static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq) } else if(strcmp(line, "%REASON%") == 0) { READ_NEXT(); info->reason = (alpm_pkgreason_t)atoi(line); + } else if(strcmp(line, "%VALIDATION%") == 0) { + alpm_list_t *i, *v = NULL; + READ_AND_STORE_ALL(v); + for(i = v; i; i = alpm_list_next(i)) + { + if(strcmp(i->data, "none") == 0) { + info->validation |= ALPM_PKG_VALIDATION_NONE; + } else if(strcmp(i->data, "md5") == 0) { + info->validation |= ALPM_PKG_VALIDATION_MD5SUM; + } else if(strcmp(i->data, "sha256") == 0) { + info->validation |= ALPM_PKG_VALIDATION_SHA256SUM; + } else if(strcmp(i->data, "pgp") == 0) { + info->validation |= ALPM_PKG_VALIDATION_SIGNATURE; + } else { + _alpm_log(db->handle, ALPM_LOG_WARNING, + _("unknown validation type for package %s: %s\n"), + info->name, (char *)i->data); + } + } + FREELIST(v); } else if(strcmp(line, "%SIZE%") == 0) { READ_NEXT(); info->isize = _alpm_strtoofft(line); @@ -817,6 +844,22 @@ int _alpm_local_db_write(alpm_db_t *db, alpm_pkg_t *info, alpm_dbinfrq_t inforeq fprintf(fp, "%%REASON%%\n" "%u\n\n", info->reason); } + if(info->validation) { + fputs("%VALIDATION%\n", fp); + if(info->validation & ALPM_PKG_VALIDATION_NONE) { + fputs("none\n", fp); + } + if(info->validation & ALPM_PKG_VALIDATION_MD5SUM) { + fputs("md5\n", fp); + } + if(info->validation & ALPM_PKG_VALIDATION_SHA256SUM) { + fputs("sha256\n", fp); + } + if(info->validation & ALPM_PKG_VALIDATION_SIGNATURE) { + fputs("pgp\n", fp); + } + fprintf(fp, "\n"); + } if(info->depends) { fputs("%DEPENDS%\n", fp); for(lp = info->depends; lp; lp = lp->next) { diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c index 4b43f21..0a8bbf3 100644 --- a/lib/libalpm/be_package.c +++ b/lib/libalpm/be_package.c @@ -341,6 +341,7 @@ int _alpm_pkg_validate_internal(alpm_handle_t *handle, if(_alpm_test_checksum(pkgfile, syncpkg->md5sum, ALPM_CSUM_MD5) != 0) { RET_ERR(handle, ALPM_ERR_PKG_INVALID_CHECKSUM, -1); } + syncpkg->validation |= ALPM_PKG_VALIDATION_MD5SUM; } if(syncpkg->sha256sum) { @@ -349,6 +350,7 @@ int _alpm_pkg_validate_internal(alpm_handle_t *handle, if(_alpm_test_checksum(pkgfile, syncpkg->sha256sum, ALPM_CSUM_SHA256) != 0) { RET_ERR(handle, ALPM_ERR_PKG_INVALID_CHECKSUM, -1); } + syncpkg->validation |= ALPM_PKG_VALIDATION_SHA256SUM; } } @@ -362,6 +364,13 @@ int _alpm_pkg_validate_internal(alpm_handle_t *handle, handle->pm_errno = ALPM_ERR_PKG_INVALID_SIG; return -1; } + if (syncpkg && has_sig) { + syncpkg->validation |= ALPM_PKG_VALIDATION_SIGNATURE; + } + } + + if (syncpkg && !syncpkg->validation) { + syncpkg->validation = ALPM_PKG_VALIDATION_NONE; } return 0; @@ -495,6 +504,7 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle, newpkg->ops = get_file_pkg_ops(); newpkg->handle = handle; newpkg->infolevel = INFRQ_BASE | INFRQ_DESC | INFRQ_SCRIPTLET; + newpkg->validation = ALPM_PKG_VALIDATION_NONE; if(full) { if(files) { @@ -539,6 +549,13 @@ int SYMEXPORT alpm_pkg_load(alpm_handle_t *handle, const char *filename, int ful return -1; } + char *sigpath = _alpm_sigpath(handle, filename); + if(sigpath && !_alpm_access(handle, NULL, sigpath, R_OK)) { + /* package validation was done with a signature */ + (*pkg)->validation = ALPM_PKG_VALIDATION_SIGNATURE; + } + free(sigpath); + return 0; } diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index 68fec16..5abfd72 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -91,6 +91,7 @@ static const char *_pkg_get_packager(alpm_pkg_t *pkg) { return pkg->packager; static const char *_pkg_get_arch(alpm_pkg_t *pkg) { return pkg->arch; } static off_t _pkg_get_isize(alpm_pkg_t *pkg) { return pkg->isize; } static alpm_pkgreason_t _pkg_get_reason(alpm_pkg_t *pkg) { return pkg->reason; } +static alpm_pkgvalidation_t _pkg_get_validation(alpm_pkg_t *pkg) { return pkg->validation; } static int _pkg_has_scriptlet(alpm_pkg_t *pkg) { return pkg->scriptlet; } static alpm_list_t *_pkg_get_licenses(alpm_pkg_t *pkg) { return pkg->licenses; } @@ -134,6 +135,7 @@ struct pkg_operations default_pkg_ops = { .get_arch = _pkg_get_arch, .get_isize = _pkg_get_isize, .get_reason = _pkg_get_reason, + .get_validation = _pkg_get_validation, .has_scriptlet = _pkg_has_scriptlet, .get_licenses = _pkg_get_licenses, @@ -268,6 +270,13 @@ alpm_pkgreason_t SYMEXPORT alpm_pkg_get_reason(alpm_pkg_t *pkg) return pkg->ops->get_reason(pkg); } +alpm_pkgvalidation_t SYMEXPORT alpm_pkg_get_validation(alpm_pkg_t *pkg) +{ + ASSERT(pkg != NULL, return -1); + pkg->handle->pm_errno = 0; + return pkg->ops->get_validation(pkg); +} + alpm_list_t SYMEXPORT *alpm_pkg_get_licenses(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return NULL); diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h index 172d2f3..0c0973e 100644 --- a/lib/libalpm/package.h +++ b/lib/libalpm/package.h @@ -47,6 +47,7 @@ struct pkg_operations { const char *(*get_arch) (alpm_pkg_t *); off_t (*get_isize) (alpm_pkg_t *); alpm_pkgreason_t (*get_reason) (alpm_pkg_t *); + alpm_pkgvalidation_t (*get_validation) (alpm_pkg_t *); int (*has_scriptlet) (alpm_pkg_t *); alpm_list_t *(*get_licenses) (alpm_pkg_t *); @@ -96,6 +97,7 @@ struct __alpm_pkg_t { int scriptlet; alpm_pkgreason_t reason; + alpm_pkgvalidation_t validation; alpm_dbinfrq_t infolevel; alpm_pkgfrom_t origin; /* origin == PKG_FROM_FILE, use pkg->origin_data.file diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index 468438f..68630c1 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -1083,6 +1083,8 @@ static int load_packages(alpm_handle_t *handle, alpm_list_t **data, free(filepath); /* copy over the install reason */ pkgfile->reason = spkg->reason; + /* copy over validation method */ + pkgfile->validation = spkg->validation; i->data = pkgfile; /* spkg has been removed from the target list, so we can free the * sync-specific fields */ diff --git a/src/pacman/package.c b/src/pacman/package.c index ecf5745..5f824f4 100644 --- a/src/pacman/package.c +++ b/src/pacman/package.c @@ -63,6 +63,7 @@ static void deplist_display(const char *title, void dump_pkg_full(alpm_pkg_t *pkg, int extra) { const char *reason; + alpm_list_t *validation = NULL; time_t bdate, idate; char bdatestr[50] = "", idatestr[50] = ""; const char *label; @@ -94,6 +95,27 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra) break; } + if(from == PKG_FROM_LOCALDB) { + alpm_pkgvalidation_t v = alpm_pkg_get_validation(pkg); + if(v) { + if(v & ALPM_PKG_VALIDATION_NONE) { + validation = alpm_list_add(validation, strdup(_("None"))); + } else { + if(v & ALPM_PKG_VALIDATION_MD5SUM) { + validation = alpm_list_add(validation, strdup(_("MD5 Sum"))); + } + if(v & ALPM_PKG_VALIDATION_SHA256SUM) { + validation = alpm_list_add(validation, strdup(_("SHA256 Sum"))); + } + if(v & ALPM_PKG_VALIDATION_SIGNATURE) { + validation = alpm_list_add(validation, strdup(_("Signature"))); + } + } + } else { + validation = alpm_list_add(validation, strdup(_("Unknown"))); + } + } + if(extra || from == PKG_FROM_LOCALDB) { /* compute this here so we don't get a pause in the middle of output */ requiredby = alpm_pkg_compute_requiredby(pkg); @@ -159,6 +181,9 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra) } alpm_siglist_cleanup(&siglist); } + if(from == PKG_FROM_LOCALDB) { + list_display(_("Validated By :"), validation); + } string_display(_("Description :"), alpm_pkg_get_desc(pkg)); /* Print additional package info if info flag passed more than once */ -- 1.7.9.1
The enum alpm_pkgvalidation_t is essentially a more generic version of _alpm_csum, so use it instead. Signed-off-by: Allan McRae <allan@archlinux.org> --- lib/libalpm/be_package.c | 4 ++-- lib/libalpm/package.c | 2 +- lib/libalpm/sync.c | 2 +- lib/libalpm/util.c | 6 +++--- lib/libalpm/util.h | 7 +------ 5 files changed, 8 insertions(+), 13 deletions(-) diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c index 0a8bbf3..fc4a05b 100644 --- a/lib/libalpm/be_package.c +++ b/lib/libalpm/be_package.c @@ -338,7 +338,7 @@ int _alpm_pkg_validate_internal(alpm_handle_t *handle, if(syncpkg->md5sum && !syncpkg->sha256sum) { _alpm_log(handle, ALPM_LOG_DEBUG, "md5sum: %s\n", syncpkg->md5sum); _alpm_log(handle, ALPM_LOG_DEBUG, "checking md5sum for %s\n", pkgfile); - if(_alpm_test_checksum(pkgfile, syncpkg->md5sum, ALPM_CSUM_MD5) != 0) { + if(_alpm_test_checksum(pkgfile, syncpkg->md5sum, ALPM_PKG_VALIDATION_MD5SUM) != 0) { RET_ERR(handle, ALPM_ERR_PKG_INVALID_CHECKSUM, -1); } syncpkg->validation |= ALPM_PKG_VALIDATION_MD5SUM; @@ -347,7 +347,7 @@ int _alpm_pkg_validate_internal(alpm_handle_t *handle, if(syncpkg->sha256sum) { _alpm_log(handle, ALPM_LOG_DEBUG, "sha256sum: %s\n", syncpkg->sha256sum); _alpm_log(handle, ALPM_LOG_DEBUG, "checking sha256sum for %s\n", pkgfile); - if(_alpm_test_checksum(pkgfile, syncpkg->sha256sum, ALPM_CSUM_SHA256) != 0) { + if(_alpm_test_checksum(pkgfile, syncpkg->sha256sum, ALPM_PKG_VALIDATION_SHA256SUM) != 0) { RET_ERR(handle, ALPM_ERR_PKG_INVALID_CHECKSUM, -1); } syncpkg->validation |= ALPM_PKG_VALIDATION_SHA256SUM; diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index 5abfd72..e881a51 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -67,7 +67,7 @@ int SYMEXPORT alpm_pkg_checkmd5sum(alpm_pkg_t *pkg) fpath = _alpm_filecache_find(pkg->handle, pkg->filename); - retval = _alpm_test_checksum(fpath, pkg->md5sum, ALPM_CSUM_MD5); + retval = _alpm_test_checksum(fpath, pkg->md5sum, ALPM_PKG_VALIDATION_MD5SUM); if(retval == 0) { return 0; diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index 68630c1..f41ecfa 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -780,7 +780,7 @@ static int validate_deltas(alpm_handle_t *handle, alpm_list_t *deltas) alpm_delta_t *d = i->data; char *filepath = _alpm_filecache_find(handle, d->delta); - if(_alpm_test_checksum(filepath, d->delta_md5, ALPM_CSUM_MD5)) { + if(_alpm_test_checksum(filepath, d->delta_md5, ALPM_PKG_VALIDATION_MD5SUM)) { errors = alpm_list_add(errors, filepath); } else { FREE(filepath); diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index 5986124..5cb75e2 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -904,14 +904,14 @@ char SYMEXPORT *alpm_compute_sha256sum(const char *filename) * error */ int _alpm_test_checksum(const char *filepath, const char *expected, - enum _alpm_csum type) + alpm_pkgvalidation_t type) { char *computed; int ret; - if(type == ALPM_CSUM_MD5) { + if(type == ALPM_PKG_VALIDATION_MD5SUM) { computed = alpm_compute_md5sum(filepath); - } else if(type == ALPM_CSUM_SHA256) { + } else if(type == ALPM_PKG_VALIDATION_SHA256SUM) { computed = alpm_compute_sha256sum(filepath); } else { return -1; diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h index d5cf012..cc5ac7b 100644 --- a/lib/libalpm/util.h +++ b/lib/libalpm/util.h @@ -105,11 +105,6 @@ struct archive_read_buffer { int ret; }; -enum _alpm_csum { - ALPM_CSUM_MD5, - ALPM_CSUM_SHA256, -}; - int _alpm_makepath(const char *path); int _alpm_makepath_mode(const char *path, mode_t mode); int _alpm_copyfile(const char *src, const char *dest); @@ -130,7 +125,7 @@ int _alpm_str_cmp(const void *s1, const void *s2); char *_alpm_filecache_find(alpm_handle_t *handle, const char *filename); const char *_alpm_filecache_setup(alpm_handle_t *handle); int _alpm_lstat(const char *path, struct stat *buf); -int _alpm_test_checksum(const char *filepath, const char *expected, enum _alpm_csum type); +int _alpm_test_checksum(const char *filepath, const char *expected, alpm_pkgvalidation_t type); int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b); int _alpm_splitname(const char *target, char **name, char **version, unsigned long *name_hash); -- 1.7.9.1
Unify the output for local and sync packages by only printing a list of possible validation types for sync packages. This also has the advantage of not printing the very long sha256 checksum which line wrapped on a standard width terminal. Signed-off-by: Allan McRae <allan@archlinux.org> --- lib/libalpm/be_sync.c | 24 ++++++++++++++++++++++++ src/pacman/package.c | 44 ++++++++++++++++++-------------------------- 2 files changed, 42 insertions(+), 26 deletions(-) diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index a686def..a124dfa 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -296,6 +296,29 @@ cleanup: static int sync_db_read(alpm_db_t *db, struct archive *archive, struct archive_entry *entry, alpm_pkg_t **likely_pkg); +static alpm_pkgvalidation_t _sync_get_validation(alpm_pkg_t *pkg) +{ + if(pkg->validation) { + return pkg->validation; + } + + if(pkg->md5sum) { + pkg->validation |= ALPM_PKG_VALIDATION_MD5SUM; + } + if(pkg->sha256sum) { + pkg->validation |= ALPM_PKG_VALIDATION_SHA256SUM; + } + if(pkg->base64_sig) { + pkg->validation |= ALPM_PKG_VALIDATION_SIGNATURE; + } + + if(!pkg->validation) { + pkg->validation |= ALPM_PKG_VALIDATION_NONE; + } + + return pkg->validation; +} + static alpm_pkg_t *load_pkg_for_entry(alpm_db_t *db, const char *entryname, const char **entry_filename, alpm_pkg_t *likely_pkg) { @@ -337,6 +360,7 @@ static alpm_pkg_t *load_pkg_for_entry(alpm_db_t *db, const char *entryname, pkg->origin = PKG_FROM_SYNCDB; pkg->origin_data.db = db; pkg->ops = &default_pkg_ops; + pkg->ops->get_validation = _sync_get_validation; pkg->handle = db->handle; /* add to the collection */ diff --git a/src/pacman/package.c b/src/pacman/package.c index 5f824f4..6f78e56 100644 --- a/src/pacman/package.c +++ b/src/pacman/package.c @@ -95,25 +95,23 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra) break; } - if(from == PKG_FROM_LOCALDB) { - alpm_pkgvalidation_t v = alpm_pkg_get_validation(pkg); - if(v) { - if(v & ALPM_PKG_VALIDATION_NONE) { - validation = alpm_list_add(validation, strdup(_("None"))); - } else { - if(v & ALPM_PKG_VALIDATION_MD5SUM) { - validation = alpm_list_add(validation, strdup(_("MD5 Sum"))); - } - if(v & ALPM_PKG_VALIDATION_SHA256SUM) { - validation = alpm_list_add(validation, strdup(_("SHA256 Sum"))); - } - if(v & ALPM_PKG_VALIDATION_SIGNATURE) { - validation = alpm_list_add(validation, strdup(_("Signature"))); - } - } + alpm_pkgvalidation_t v = alpm_pkg_get_validation(pkg); + if(v) { + if(v & ALPM_PKG_VALIDATION_NONE) { + validation = alpm_list_add(validation, strdup(_("None"))); } else { - validation = alpm_list_add(validation, strdup(_("Unknown"))); + if(v & ALPM_PKG_VALIDATION_MD5SUM) { + validation = alpm_list_add(validation, strdup(_("MD5 Sum"))); + } + if(v & ALPM_PKG_VALIDATION_SHA256SUM) { + validation = alpm_list_add(validation, strdup(_("SHA256 Sum"))); + } + if(v & ALPM_PKG_VALIDATION_SIGNATURE) { + validation = alpm_list_add(validation, strdup(_("Signature"))); + } } + } else { + validation = alpm_list_add(validation, strdup(_("Unknown"))); } if(extra || from == PKG_FROM_LOCALDB) { @@ -162,12 +160,8 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra) alpm_pkg_has_scriptlet(pkg) ? _("Yes") : _("No")); } - if(from == PKG_FROM_SYNCDB) { - string_display(_("MD5 Sum :"), alpm_pkg_get_md5sum(pkg)); - string_display(_("SHA256 Sum :"), alpm_pkg_get_sha256sum(pkg)); - string_display(_("Signatures :"), - alpm_pkg_get_base64_sig(pkg) ? _("Yes") : _("None")); - } + list_display(_("Validated By :"), validation); + if(from == PKG_FROM_FILE) { alpm_siglist_t siglist; int err = alpm_pkg_check_pgp_signature(pkg, &siglist); @@ -181,9 +175,7 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra) } alpm_siglist_cleanup(&siglist); } - if(from == PKG_FROM_LOCALDB) { - list_display(_("Validated By :"), validation); - } + string_display(_("Description :"), alpm_pkg_get_desc(pkg)); /* Print additional package info if info flag passed more than once */ -- 1.7.9.1
participants (1)
-
Allan McRae