[pacman-dev] [PATCH] Add information on how an installed package was validated
Allan McRae
allan at archlinux.org
Sat Feb 18 01:42:49 EST 2012
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 at 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;
+
/** 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;
}
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)) {
+ 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
More information about the pacman-dev
mailing list