summaryrefslogtreecommitdiff
path: root/lib/package.c
diff options
context:
space:
mode:
authorjbj <devnull@localhost>2001-10-26 04:16:19 +0000
committerjbj <devnull@localhost>2001-10-26 04:16:19 +0000
commit4a1a5e81483a2f81b22c3a0d2cb054d93055998e (patch)
tree13e0de60dd990c9e799bc0975c80741b1b5880de /lib/package.c
parentf03b462b1ef0ad128b7732c0492eefeff9c2248e (diff)
downloadrpm-4a1a5e81483a2f81b22c3a0d2cb054d93055998e.tar.gz
rpm-4a1a5e81483a2f81b22c3a0d2cb054d93055998e.tar.bz2
rpm-4a1a5e81483a2f81b22c3a0d2cb054d93055998e.zip
- wire transactions through rpmcli install/erase modes.
- legacy signatures always checked on package read. CVS patchset: 5134 CVS date: 2001/10/26 04:16:19
Diffstat (limited to 'lib/package.c')
-rw-r--r--lib/package.c208
1 files changed, 178 insertions, 30 deletions
diff --git a/lib/package.c b/lib/package.c
index dea9941f1..0dc889972 100644
--- a/lib/package.c
+++ b/lib/package.c
@@ -6,16 +6,21 @@
#include <netinet/in.h>
+#include <rpmio_internal.h>
#include <rpmlib.h>
+#include "depends.h"
+
#include "misc.h" /* XXX stripTrailingChar() */
#include "legacy.h" /* XXX providePackageNVR() and compressFileList() */
#include "rpmlead.h"
+
#include "signature.h"
#include "debug.h"
#define alloca_strdup(_s) strcpy(alloca(strlen(_s)+1), (_s))
+/*@access rpmTransactionSet@*/
/*@access Header@*/ /* XXX compared with NULL */
void headerMergeLegacySigs(Header h, const Header sig)
@@ -118,6 +123,7 @@ Header headerRegenSigHeader(const Header h)
return sig;
}
+#ifdef DYING
/**
* Retrieve package components from file handle.
* @param fd file handle
@@ -175,9 +181,7 @@ static rpmRC readPackageHeaders(FD_t fd,
return RPMRC_FAIL;
}
- /*
- * Convert legacy headers on the fly ...
- */
+ /* Convert legacy headers on the fly ... */
legacyRetrofit(*hdr, lead);
break;
default:
@@ -192,40 +196,184 @@ static rpmRC readPackageHeaders(FD_t fd,
return RPMRC_OK;
}
+#endif
-rpmRC rpmReadPackageInfo(FD_t fd, Header * sigp, Header * hdrp)
+int rpmReadPackageFile(rpmTransactionSet ts, FD_t fd,
+ const char * fn, Header * hdrp)
{
- rpmRC rc = readPackageHeaders(fd, NULL, sigp, hdrp);
- if (rc != RPMRC_OK)
- return rc;
- if (hdrp == NULL || sigp == NULL)
- return rc;
- if (*hdrp && *sigp)
- headerMergeLegacySigs(*hdrp, *sigp);
- return rc;
-}
+ byte buf[8*BUFSIZ];
+ ssize_t count;
+ struct rpmlead * l = alloca(sizeof(*l));
+ Header sig;
+ Header h = NULL;
+ int hmagic;
+ rpmRC rc = RPMRC_FAIL; /* assume failure */
+ int xx;
+ int i;
-rpmRC rpmReadPackageHeader(FD_t fd, Header * hdrp, int * isSource, int * major,
- int * minor)
-{
- struct rpmlead lead;
- Header sig = NULL;
- rpmRC rc = readPackageHeaders(fd, &lead, &sig, hdrp);
+ { struct stat st;
+ memset(&st, 0, sizeof(st));
+ (void) fstat(Fileno(fd), &st);
+ /* if fd points to a socket, pipe, etc, st.st_size is *always* zero */
+ if (S_ISREG(st.st_mode) && st.st_size < sizeof(*l))
+ goto exit;
+ }
- if (rc != RPMRC_OK)
+ memset(l, 0, sizeof(*l));
+ if (readLead(fd, l)) {
+ rpmError(RPMERR_READLEAD, _("%s: readLead failed\n"), fn);
goto exit;
+ }
- if (hdrp && *hdrp && sig) {
- headerMergeLegacySigs(*hdrp, sig);
- sig = rpmFreeSignature(sig);
+ if (l->magic[0] != RPMLEAD_MAGIC0 || l->magic[1] != RPMLEAD_MAGIC1
+ || l->magic[2] != RPMLEAD_MAGIC2 || l->magic[3] != RPMLEAD_MAGIC3) {
+ rpmError(RPMERR_READLEAD, _("%s: bad magic\n"), fn);
+ rc = RPMRC_BADMAGIC;
+ goto exit;
}
-
- if (isSource) *isSource = lead.type == RPMLEAD_SOURCE;
- /*@-mods@*/ /* FIX: undocumented modification */
- if (major) *major = lead.major;
- if (minor) *minor = lead.minor;
- /*@=mods@*/
-
+
+ switch (l->major) {
+ case 1:
+ rpmError(RPMERR_NEWPACKAGE,
+ _("packaging version 1 is not supported by this version of RPM\n"));
+ goto exit;
+ /*@notreached@*/ break;
+ case 2:
+ case 3:
+ case 4:
+ break;
+ default:
+ rpmError(RPMERR_NEWPACKAGE, _("only packaging with major numbers <= 4 "
+ "is supported by this version of RPM\n"));
+ goto exit;
+ /*@notreached@*/ break;
+ }
+
+ rc = rpmReadSignature(fd, &sig, l->signature_type);
+ if (!(rc == RPMRC_OK || rc == RPMRC_BADSIZE)) {
+ rpmError(RPMERR_SIGGEN, _("%s: rpmReadSignature failed\n"), fn);
+ goto exit;
+ }
+ if (sig == NULL) {
+ rpmError(RPMERR_SIGGEN, _("%s: No signature available\n"), fn);
+ rc = RPMRC_FAIL;
+ goto exit;
+ }
+
+ if (ts->need_payload) /* leave fd ready to install payload */
+ ts->sigtag = 0;
+ else if (headerIsEntry(sig, RPMSIGTAG_GPG))
+ ts->sigtag = RPMSIGTAG_GPG;
+ else if (headerIsEntry(sig, RPMSIGTAG_PGP))
+ ts->sigtag = RPMSIGTAG_PGP;
+ else if (headerIsEntry(sig, RPMSIGTAG_MD5))
+ ts->sigtag = RPMSIGTAG_MD5;
+ else
+ ts->sigtag = 0;
+
+ /*@-type@*/ /* FIX: cast? */
+ if (ts->sigtag == RPMSIGTAG_GPG)
+ fdInitDigest(fd, PGPHASHALGO_SHA1, 0);
+ else if (ts->sigtag == RPMSIGTAG_PGP || ts->sigtag == RPMSIGTAG_MD5)
+ fdInitDigest(fd, PGPHASHALGO_MD5, 0);
+ /*@=type@*/
+
+ hmagic = ((l->major >= 3) ? HEADER_MAGIC_YES : HEADER_MAGIC_NO);
+ h = headerRead(fd, hmagic);
+ if (h == NULL) {
+ rpmError(RPMERR_FREAD, _("%s: headerRead failed\n"), fn);
+ rc = RPMRC_FAIL;
+ goto exit;
+ }
+
+ /* Any signatures to check? */
+ if (ts->sigtag == 0) {
+ rc = RPMRC_OK;
+ goto exit;
+ }
+
+ ts->dig = pgpNewDig();
+ ts->dig->nbytes = headerSizeof(h, hmagic);
+
+ /* Read the compressed payload. */
+ while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), fd)) > 0)
+ ts->dig->nbytes += count;
+
+ if (count < 0) {
+ rpmError(RPMERR_FREAD, _("%s: Fread failed: %s\n"), fn, Fstrerror(fd));
+ rc = RPMRC_FAIL;
+ goto exit;
+ }
+ ts->dig->nbytes += count;
+
+ xx = headerGetEntry(sig, ts->sigtag, &ts->sigtype,
+ (void **) &ts->sig, &ts->siglen);
+
+ xx = pgpPrtPkts(ts->sig, ts->siglen, ts->dig, rpmIsDebug());
+
+ /*@-type@*/ /* FIX: cast? */
+ for (i = fd->ndigests - 1; i >= 0; i--) {
+ FDDIGEST_t fddig = fd->digests + i;
+ if (fddig->hashctx == NULL)
+ continue;
+ if (fddig->hashalgo == PGPHASHALGO_MD5) {
+ /*@-branchstate@*/
+ if (ts->dig->md5ctx != NULL)
+ (void) rpmDigestFinal(ts->dig->md5ctx, NULL, NULL, 0);
+ /*@=branchstate@*/
+ ts->dig->md5ctx = fddig->hashctx;
+ fddig->hashctx = NULL;
+ continue;
+ }
+ if (fddig->hashalgo == PGPHASHALGO_SHA1) {
+ /*@-branchstate@*/
+ if (ts->dig->sha1ctx != NULL)
+ (void) rpmDigestFinal(ts->dig->sha1ctx, NULL, NULL, 0);
+ /*@=branchstate@*/
+ ts->dig->sha1ctx = fddig->hashctx;
+ fddig->hashctx = NULL;
+ continue;
+ }
+ }
+ /*@=type@*/
+
+/** @todo Implement disable/enable/warn/error/anal policy. */
+
+ buf[0] = '\0';
+ switch (rpmVerifySignature(ts, buf)) {
+ case RPMSIG_OK: /*!< Signature is OK. */
+ rpmMessage(RPMMESS_VERBOSE, "%s: %s", fn, buf);
+ rc = RPMRC_OK;
+ break;
+ case RPMSIG_UNKNOWN: /*!< Signature is unknown. */
+ case RPMSIG_NOKEY: /*!< Key is unavailable. */
+ case RPMSIG_NOTTRUSTED: /*!< Signature is OK, but key is not trusted. */
+ rpmMessage(RPMMESS_WARNING, "%s: %s", fn, buf);
+ rc = RPMRC_OK;
+ break;
+ default:
+ case RPMSIG_BAD: /*!< Signature does not verify. */
+ rpmMessage(RPMMESS_ERROR, "%s: %s", fn, buf);
+ rc = RPMRC_OK;
+ break;
+ }
+
exit:
+ if (rc == 0 && hdrp != NULL) {
+ /* Convert legacy headers on the fly ... */
+ legacyRetrofit(h, l);
+
+ /* Append (and remap) signature tags. */
+ headerMergeLegacySigs(h, sig);
+
+ /* Bump reference count for return. */
+ *hdrp = headerLink(h);
+ }
+ h = headerFree(h);
+ if (ts->sig != NULL)
+ ts->sig = headerFreeData(ts->sig, ts->sigtype);
+ if (ts->dig != NULL)
+ ts->dig = pgpFreeDig(ts->dig);
+ sig = rpmFreeSignature(sig);
return rc;
}