On Sat, Feb 18, 2012 at 12:42 AM, Allan McRae <al...@archlinux.org> wrote: > 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 <al...@archlinux.org> > --- > > The only thing I am concerned about is setting the validation level for > "pacman -U" operations. During the actual validation step we do not have > the package struct yet so there is nowhere to store whether or not a > signature is checked. If there is a .sig file present after loading the > package (which occurs immediately after signature verification), it is > just assumed that the .sig file was checked. > > lib/libalpm/alpm.h | 15 +++++++++++++++ > lib/libalpm/be_local.c | 14 ++++++++++++++ > 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 | 24 ++++++++++++++++++++++++ > 7 files changed, 83 insertions(+), 0 deletions(-) > > diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h > index aeb1bb7..eafe931 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, > + ALPM_PKG_VALIDATION_MD5SUM, > + ALPM_PKG_VALIDATION_SHA256SUM, > + ALPM_PKG_VALIDATION_SIGNATURE > +} alpm_pkgvalidation_t; It might be smart to make these bitmask values- that way, you could store the fact that we checked both a signature and an MD5 sum, for instance. We don't do this now but seems trivial to allow that to be stored. (See enum _alpm_loglevel_t for an example).
> + > /** Types of version constraints in dependency specs. */ > typedef enum _alpm_depmod_t { > /** No version constraint */ > @@ -879,6 +888,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..40b273d 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,9 @@ 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) { > + READ_NEXT(); > + info->validation = > (alpm_pkgvalidation_t)atoi(line); > } else if(strcmp(line, "%SIZE%") == 0) { > READ_NEXT(); > info->isize = _alpm_strtoofft(line); > @@ -817,6 +827,10 @@ 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) { > + fprintf(fp, "%%VALIDATION%%\n" > + "%u\n\n", > info->validation); > + } > 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..06b4037 100644 > --- a/lib/libalpm/be_package.c > +++ b/lib/libalpm/be_package.c > @@ -320,6 +320,10 @@ int _alpm_pkg_validate_internal(alpm_handle_t *handle, > RET_ERR(handle, ALPM_ERR_PKG_NOT_FOUND, -1); > } > > + if (syncpkg) { > + syncpkg->validation = ALPM_PKG_VALIDATION_NONE; > + } > + > /* can we get away with skipping checksums? */ > has_sig = 0; > if(level & ALPM_SIG_PACKAGE) { > @@ -341,6 +345,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; Mentioned this to you on IRC, but unifying the ALPM_CSUM_* enum and your new one would be a great idea. > } > > if(syncpkg->sha256sum) { > @@ -349,6 +354,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 +368,9 @@ int _alpm_pkg_validate_internal(alpm_handle_t *handle, > handle->pm_errno = ALPM_ERR_PKG_INVALID_SIG; > return -1; > } > + if (syncpkg) { > + syncpkg->validation = ALPM_PKG_VALIDATION_SIGNATURE; > + } > } > > 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..2345d30 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; > + const char *validation = NULL; > time_t bdate, idate; > char bdatestr[50] = "", idatestr[50] = ""; > const char *label; > @@ -94,6 +95,26 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra) > break; > } > > + if(from == PKG_FROM_LOCALDB) { > + switch(alpm_pkg_get_validation(pkg)) { What is the return code of this method for sync packages? I'm wondering if you should leave it unprotected like the reason stuff already is; even if we don't end up displaying it, it isn't that expensive to do. Additionally, it might make sense to use this same method to simplify our -Si display. Current: $ pacman -Si pacman Repository : core Name : pacman ... Build Date : Sat 11 Feb 2012 03:36:23 PM CST MD5 Sum : 1999200ccee8d823118ebbe61ce48c58 SHA256 Sum : 0a7d4e439ea565de41aadaaf75ea8752722fdfa3d147686f6aa080857fabdd3a Signatures : Yes Description : A library-based package manager with dependency support Proposed: $ pacman -Si pacman Repository : core Name : pacman ... Build Date : Sat 11 Feb 2012 03:36:23 PM CST Validated By : MD5 Checksum, SHA256 Checksum, PGP Signature Description : A library-based package manager with dependency support > + case ALPM_PKG_VALIDATION_NONE: > + validation = _("None"); > + break; > + case ALPM_PKG_VALIDATION_MD5SUM: > + validation = _("MD5 Sum"); > + break; > + case ALPM_PKG_VALIDATION_SHA256SUM: > + validation = _("SHA256 Sum"); > + break; > + case ALPM_PKG_VALIDATION_SIGNATURE: > + validation = _("Signature"); > + break; > + default: > + validation = _("Unknown"); > + break; > + } > + } > + > 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 +180,9 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra) > } > alpm_siglist_cleanup(&siglist); > } > + if(from == PKG_FROM_LOCALDB) { > + string_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 > >