|
|
629b27 |
From a4755a5ed793ca439bb23b804ba7a8ab080ff110 Mon Sep 17 00:00:00 2001
|
|
|
629b27 |
From: chantra <chantr4@gmail.com>
|
|
|
629b27 |
Date: Fri, 28 Jan 2022 19:19:45 -0800
|
|
|
629b27 |
Subject: [PATCH 07/30] [rpm2extents] write RC and output to transcodedfile
|
|
|
629b27 |
metadata
|
|
|
629b27 |
|
|
|
629b27 |
create a new rpmcliVerifySignaturesFD function which takes a custom callback
|
|
|
629b27 |
that allows collecting a textual output of the validation, similar to what
|
|
|
629b27 |
rpmsign command would give.
|
|
|
629b27 |
---
|
|
|
629b27 |
lib/rpmchecksig.c | 67 +++++++++++++++++++++++++++++++++++--------
|
|
|
629b27 |
lib/rpmcli.h | 5 ++--
|
|
|
629b27 |
rpm2extents.c | 73 +++++++++++++++++++++++++++++++----------------
|
|
|
629b27 |
3 files changed, 106 insertions(+), 39 deletions(-)
|
|
|
629b27 |
|
|
|
629b27 |
diff --git a/lib/rpmchecksig.c b/lib/rpmchecksig.c
|
|
|
629b27 |
index 1a6b95323..fcdbb424f 100644
|
|
|
629b27 |
--- a/lib/rpmchecksig.c
|
|
|
629b27 |
+++ b/lib/rpmchecksig.c
|
|
|
629b27 |
@@ -260,6 +260,29 @@ exit:
|
|
|
629b27 |
return rc;
|
|
|
629b27 |
}
|
|
|
629b27 |
|
|
|
629b27 |
+static int rpmpkgVerifySigsFD(rpmKeyring keyring, int vfylevel, rpmVSFlags flags,
|
|
|
629b27 |
+ FD_t fd, rpmsinfoCb cb, void *cbdata)
|
|
|
629b27 |
+{
|
|
|
629b27 |
+ char *msg = NULL;
|
|
|
629b27 |
+ int rc;
|
|
|
629b27 |
+ struct rpmvs_s *vs = rpmvsCreate(vfylevel, flags, keyring);
|
|
|
629b27 |
+
|
|
|
629b27 |
+ rc = rpmpkgRead(vs, fd, NULL, NULL, &msg;;
|
|
|
629b27 |
+
|
|
|
629b27 |
+ if (rc)
|
|
|
629b27 |
+ goto exit;
|
|
|
629b27 |
+
|
|
|
629b27 |
+ rc = rpmvsVerify(vs, RPMSIG_VERIFIABLE_TYPE, cb, cbdata);
|
|
|
629b27 |
+
|
|
|
629b27 |
+exit:
|
|
|
629b27 |
+ if (rc && msg)
|
|
|
629b27 |
+ rpmlog(RPMLOG_ERR, "%s\n", msg);
|
|
|
629b27 |
+ rpmvsFree(vs);
|
|
|
629b27 |
+ free(msg);
|
|
|
629b27 |
+ return rc;
|
|
|
629b27 |
+}
|
|
|
629b27 |
+
|
|
|
629b27 |
+
|
|
|
629b27 |
/* Wrapper around rpmkVerifySigs to preserve API */
|
|
|
629b27 |
int rpmVerifySignatures(QVA_t qva, rpmts ts, FD_t fd, const char * fn)
|
|
|
629b27 |
{
|
|
|
629b27 |
@@ -305,12 +328,38 @@ int rpmcliVerifySignatures(rpmts ts, ARGV_const_t argv)
|
|
|
629b27 |
return res;
|
|
|
629b27 |
}
|
|
|
629b27 |
|
|
|
629b27 |
-int rpmcliVerifySignaturesFD(rpmts ts, FD_t fdi)
|
|
|
629b27 |
+struct vfydatafd_s {
|
|
|
629b27 |
+ size_t len;
|
|
|
629b27 |
+ char msg[BUFSIZ];
|
|
|
629b27 |
+};
|
|
|
629b27 |
+
|
|
|
629b27 |
+
|
|
|
629b27 |
+static int vfyFDCb(struct rpmsinfo_s *sinfo, void *cbdata)
|
|
|
629b27 |
{
|
|
|
629b27 |
- int res = 0;
|
|
|
629b27 |
+ struct vfydatafd_s *vd = cbdata;
|
|
|
629b27 |
+ char *vmsg, *msg;
|
|
|
629b27 |
+ size_t n;
|
|
|
629b27 |
+ size_t remainder = BUFSIZ - vd->len;
|
|
|
629b27 |
+
|
|
|
629b27 |
+ vmsg = rpmsinfoMsg(sinfo);
|
|
|
629b27 |
+ rasprintf(&msg, " %s\n", vmsg);
|
|
|
629b27 |
+ n = rstrlcpy(vd->msg + vd->len, msg, remainder);
|
|
|
629b27 |
+ free(vmsg);
|
|
|
629b27 |
+ free(msg);
|
|
|
629b27 |
+ if(n <= remainder){
|
|
|
629b27 |
+ vd->len += n;
|
|
|
629b27 |
+ }
|
|
|
629b27 |
+ return 1;
|
|
|
629b27 |
+}
|
|
|
629b27 |
+
|
|
|
629b27 |
+
|
|
|
629b27 |
+int rpmcliVerifySignaturesFD(rpmts ts, FD_t fdi, char **msg)
|
|
|
629b27 |
+{
|
|
|
629b27 |
+ rpmRC rc = RPMRC_FAIL;
|
|
|
629b27 |
rpmKeyring keyring = rpmtsGetKeyring(ts, 1);
|
|
|
629b27 |
rpmVSFlags vsflags = rpmtsVfyFlags(ts);
|
|
|
629b27 |
int vfylevel = rpmtsVfyLevel(ts);
|
|
|
629b27 |
+ struct vfydatafd_s vd = {.len = 0};
|
|
|
629b27 |
|
|
|
629b27 |
vsflags |= rpmcliVSFlags;
|
|
|
629b27 |
if (rpmcliVfyLevelMask) {
|
|
|
629b27 |
@@ -318,19 +367,13 @@ int rpmcliVerifySignaturesFD(rpmts ts, FD_t fdi)
|
|
|
629b27 |
rpmtsSetVfyLevel(ts, vfylevel);
|
|
|
629b27 |
}
|
|
|
629b27 |
|
|
|
629b27 |
- FD_t fd = fdDup(Fileno(fdi));
|
|
|
629b27 |
- if (fd == NULL || Ferror(fd)) {
|
|
|
629b27 |
- rpmlog(RPMLOG_ERR, _("fdDup failed: %s\n"), Fstrerror(fd));
|
|
|
629b27 |
- res++;
|
|
|
629b27 |
- } else if (rpmpkgVerifySigs(keyring, vfylevel, vsflags, fd, "stdin")) {
|
|
|
629b27 |
- res++;
|
|
|
629b27 |
+ if (!rpmpkgVerifySigsFD(keyring, vfylevel, vsflags, fdi, vfyFDCb, &vd)) {
|
|
|
629b27 |
+ rc = RPMRC_OK;
|
|
|
629b27 |
}
|
|
|
629b27 |
-
|
|
|
629b27 |
- lseek(Fileno(fd), SEEK_SET, 0);
|
|
|
629b27 |
- Fclose(fd);
|
|
|
629b27 |
+ *msg = strdup(vd.msg);
|
|
|
629b27 |
rpmsqPoll();
|
|
|
629b27 |
|
|
|
629b27 |
rpmKeyringFree(keyring);
|
|
|
629b27 |
- return res;
|
|
|
629b27 |
+ return rc;
|
|
|
629b27 |
}
|
|
|
629b27 |
|
|
|
629b27 |
diff --git a/lib/rpmcli.h b/lib/rpmcli.h
|
|
|
629b27 |
index 52443e459..7ff48b37a 100644
|
|
|
629b27 |
--- a/lib/rpmcli.h
|
|
|
629b27 |
+++ b/lib/rpmcli.h
|
|
|
629b27 |
@@ -413,12 +413,13 @@ int rpmcliVerifySignatures(rpmts ts, ARGV_const_t argv);
|
|
|
629b27 |
|
|
|
629b27 |
|
|
|
629b27 |
/** \ingroup rpmcli
|
|
|
629b27 |
- * Verify package signatures
|
|
|
629b27 |
+ * Verify package signatures.
|
|
|
629b27 |
* @param ts transaction set
|
|
|
629b27 |
* @param fd a file descriptor to verify
|
|
|
629b27 |
+ * @param msg a string containing textual information about the verification, similar to rpmcliVerifySignatures output.
|
|
|
629b27 |
* @return 0 on success
|
|
|
629b27 |
*/
|
|
|
629b27 |
-int rpmcliVerifySignaturesFD(rpmts ts, FD_t fd);
|
|
|
629b27 |
+int rpmcliVerifySignaturesFD(rpmts ts, FD_t fd, char **msg);
|
|
|
629b27 |
|
|
|
629b27 |
#ifdef __cplusplus
|
|
|
629b27 |
}
|
|
|
629b27 |
diff --git a/rpm2extents.c b/rpm2extents.c
|
|
|
629b27 |
index d8e582676..065a00306 100644
|
|
|
629b27 |
--- a/rpm2extents.c
|
|
|
629b27 |
+++ b/rpm2extents.c
|
|
|
629b27 |
@@ -133,16 +133,38 @@ exit:
|
|
|
629b27 |
return rc;
|
|
|
629b27 |
}
|
|
|
629b27 |
|
|
|
629b27 |
-static rpmRC validator(FD_t fdi){
|
|
|
629b27 |
+static rpmRC validator(FD_t fdi, FD_t fdo){
|
|
|
629b27 |
+ int rc;
|
|
|
629b27 |
+ char *msg = NULL;
|
|
|
629b27 |
rpmts ts = rpmtsCreate();
|
|
|
629b27 |
+ size_t len;
|
|
|
629b27 |
+
|
|
|
629b27 |
rpmtsSetRootDir(ts, rpmcliRootDir);
|
|
|
629b27 |
- /* rpmlog prints NOTICE to stdout */
|
|
|
629b27 |
- // rpmlogSetFile(stderr);
|
|
|
629b27 |
- if(rpmcliVerifySignaturesFD(ts, fdi)){
|
|
|
629b27 |
+ rc = rpmcliVerifySignaturesFD(ts, fdi, &msg;;
|
|
|
629b27 |
+ if(rc){
|
|
|
629b27 |
fprintf(stderr, _("Error validating package\n"));
|
|
|
629b27 |
- return RPMRC_FAIL;
|
|
|
629b27 |
}
|
|
|
629b27 |
- return RPMRC_OK;
|
|
|
629b27 |
+ len = sizeof(rc);
|
|
|
629b27 |
+ if (Fwrite(&rc, len, 1, fdo) != len) {
|
|
|
629b27 |
+ fprintf(stderr, _("Unable to write validator RC code %d\n"), rc);
|
|
|
629b27 |
+ goto exit;
|
|
|
629b27 |
+ }
|
|
|
629b27 |
+ size_t validator_len = msg ? strlen(msg) : 0;
|
|
|
629b27 |
+ len = sizeof(validator_len);
|
|
|
629b27 |
+ if (Fwrite(&validator_len, len, 1, fdo) != len) {
|
|
|
629b27 |
+ fprintf(stderr, _("Unable to write validator output length code %zd\n"), validator_len);
|
|
|
629b27 |
+ goto exit;
|
|
|
629b27 |
+ }
|
|
|
629b27 |
+ if (Fwrite(msg, validator_len, 1, fdo) != validator_len) {
|
|
|
629b27 |
+ fprintf(stderr, _("Unable to write validator output %s\n"), msg);
|
|
|
629b27 |
+ goto exit;
|
|
|
629b27 |
+ }
|
|
|
629b27 |
+
|
|
|
629b27 |
+exit:
|
|
|
629b27 |
+ if(msg) {
|
|
|
629b27 |
+ free(msg);
|
|
|
629b27 |
+ }
|
|
|
629b27 |
+ return rc ? RPMRC_FAIL : RPMRC_OK;
|
|
|
629b27 |
}
|
|
|
629b27 |
|
|
|
629b27 |
static rpmRC process_package(FD_t fdi, FD_t digestori, FD_t validationi)
|
|
|
629b27 |
@@ -173,7 +195,7 @@ static rpmRC process_package(FD_t fdi, FD_t digestori, FD_t validationi)
|
|
|
629b27 |
rpm_mode_t mode;
|
|
|
629b27 |
char *rpmio_flags = NULL, *zeros;
|
|
|
629b27 |
const unsigned char *digest;
|
|
|
629b27 |
- rpm_loff_t pos, size, pad, digest_pos, validation_pos;
|
|
|
629b27 |
+ rpm_loff_t pos, size, pad, digest_pos, validation_pos, digest_table_pos;
|
|
|
629b27 |
uint32_t offset_ix = 0;
|
|
|
629b27 |
size_t len;
|
|
|
629b27 |
int next = 0;
|
|
|
629b27 |
@@ -278,6 +300,16 @@ static rpmRC process_package(FD_t fdi, FD_t digestori, FD_t validationi)
|
|
|
629b27 |
qsort(offsets, (size_t)offset_ix, sizeof(struct digestoffset),
|
|
|
629b27 |
digestoffsetCmp);
|
|
|
629b27 |
|
|
|
629b27 |
+ validation_pos = pos;
|
|
|
629b27 |
+ ssize_t validation_len = ufdCopy(validationi, fdo);
|
|
|
629b27 |
+ if (validation_len == -1) {
|
|
|
629b27 |
+ fprintf(stderr, _("validation output ufdCopy failed\n"));
|
|
|
629b27 |
+ rc = RPMRC_FAIL;
|
|
|
629b27 |
+ goto exit;
|
|
|
629b27 |
+ }
|
|
|
629b27 |
+
|
|
|
629b27 |
+ digest_table_pos = validation_pos + validation_len;
|
|
|
629b27 |
+
|
|
|
629b27 |
len = sizeof(offset_ix);
|
|
|
629b27 |
if (Fwrite(&offset_ix, len, 1, fdo) != len) {
|
|
|
629b27 |
fprintf(stderr, _("Unable to write length of table\n"));
|
|
|
629b27 |
@@ -304,7 +336,7 @@ static rpmRC process_package(FD_t fdi, FD_t digestori, FD_t validationi)
|
|
|
629b27 |
}
|
|
|
629b27 |
}
|
|
|
629b27 |
digest_pos = (
|
|
|
629b27 |
- pos + sizeof(offset_ix) + sizeof(diglen) +
|
|
|
629b27 |
+ digest_table_pos + sizeof(offset_ix) + sizeof(diglen) +
|
|
|
629b27 |
offset_ix * (diglen + sizeof(rpm_loff_t))
|
|
|
629b27 |
);
|
|
|
629b27 |
|
|
|
629b27 |
@@ -315,14 +347,6 @@ static rpmRC process_package(FD_t fdi, FD_t digestori, FD_t validationi)
|
|
|
629b27 |
goto exit;
|
|
|
629b27 |
}
|
|
|
629b27 |
|
|
|
629b27 |
- validation_pos = digest_pos + digest_len;
|
|
|
629b27 |
- ssize_t validation_len = ufdCopy(validationi, fdo);
|
|
|
629b27 |
- if (validation_len == -1) {
|
|
|
629b27 |
- fprintf(stderr, _("validation output ufdCopy failed\n"));
|
|
|
629b27 |
- rc = RPMRC_FAIL;
|
|
|
629b27 |
- goto exit;
|
|
|
629b27 |
- }
|
|
|
629b27 |
-
|
|
|
629b27 |
/* add more padding so the last file can be cloned. It doesn't matter that
|
|
|
629b27 |
* the table and validation etc are in this space. In fact, it's pretty
|
|
|
629b27 |
* efficient if it is.
|
|
|
629b27 |
@@ -336,18 +360,18 @@ static rpmRC process_package(FD_t fdi, FD_t digestori, FD_t validationi)
|
|
|
629b27 |
goto exit;
|
|
|
629b27 |
}
|
|
|
629b27 |
zeros = _free(zeros);
|
|
|
629b27 |
- if (Fwrite(&pos, len, 1, fdo) != len) {
|
|
|
629b27 |
- fprintf(stderr, _("Unable to write offset of digest table\n"));
|
|
|
629b27 |
+ if (Fwrite(&validation_pos, len, 1, fdo) != len) {
|
|
|
629b27 |
+ fprintf(stderr, _("Unable to write offset of validation output\n"));
|
|
|
629b27 |
rc = RPMRC_FAIL;
|
|
|
629b27 |
goto exit;
|
|
|
629b27 |
}
|
|
|
629b27 |
- if (Fwrite(&digest_pos, len, 1, fdo) != len) {
|
|
|
629b27 |
- fprintf(stderr, _("Unable to write offset of validation table\n"));
|
|
|
629b27 |
+ if (Fwrite(&digest_table_pos, len, 1, fdo) != len) {
|
|
|
629b27 |
+ fprintf(stderr, _("Unable to write offset of digest table\n"));
|
|
|
629b27 |
rc = RPMRC_FAIL;
|
|
|
629b27 |
goto exit;
|
|
|
629b27 |
}
|
|
|
629b27 |
- if (Fwrite(&validation_pos, len, 1, fdo) != len) {
|
|
|
629b27 |
- fprintf(stderr, _("Unable to write offset of validation output\n"));
|
|
|
629b27 |
+ if (Fwrite(&digest_pos, len, 1, fdo) != len) {
|
|
|
629b27 |
+ fprintf(stderr, _("Unable to write offset of validation table\n"));
|
|
|
629b27 |
rc = RPMRC_FAIL;
|
|
|
629b27 |
goto exit;
|
|
|
629b27 |
}
|
|
|
629b27 |
@@ -431,11 +455,9 @@ static int teeRpm(FD_t fdi, FD_t digestori) {
|
|
|
629b27 |
close(validatorpipefd[1]);
|
|
|
629b27 |
close(rpmsignpipefd[0]);
|
|
|
629b27 |
FD_t fdi = fdDup(validatorpipefd[0]);
|
|
|
629b27 |
- // redirect STDOUT to the pipe
|
|
|
629b27 |
- close(STDOUT_FILENO);
|
|
|
629b27 |
FD_t fdo = fdDup(rpmsignpipefd[1]);
|
|
|
629b27 |
close(rpmsignpipefd[1]);
|
|
|
629b27 |
- rc = validator(fdi);
|
|
|
629b27 |
+ rc = validator(fdi, fdo);
|
|
|
629b27 |
if(rc != RPMRC_OK) {
|
|
|
629b27 |
fprintf(stderr, _("Validator failed\n"));
|
|
|
629b27 |
}
|
|
|
629b27 |
@@ -486,6 +508,7 @@ static int teeRpm(FD_t fdi, FD_t digestori) {
|
|
|
629b27 |
close(rpmsignpipefd[0]);
|
|
|
629b27 |
close(rpmsignpipefd[1]);
|
|
|
629b27 |
|
|
|
629b27 |
+ rc = RPMRC_OK;
|
|
|
629b27 |
offt = ufdTee(fdi, fds, 2);
|
|
|
629b27 |
if(offt == -1){
|
|
|
629b27 |
fprintf(stderr, _("Failed to tee RPM\n"));
|
|
|
629b27 |
--
|
|
|
629b27 |
2.35.1
|
|
|
629b27 |
|