diff options
author | jbj <devnull@localhost> | 2001-10-26 04:16:19 +0000 |
---|---|---|
committer | jbj <devnull@localhost> | 2001-10-26 04:16:19 +0000 |
commit | 4a1a5e81483a2f81b22c3a0d2cb054d93055998e (patch) | |
tree | 13e0de60dd990c9e799bc0975c80741b1b5880de /lib/package.c | |
parent | f03b462b1ef0ad128b7732c0492eefeff9c2248e (diff) | |
download | rpm-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.c | 208 |
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; } |