static void unloadImmutableRegion(Header *hdrp, rpmTagVal tag) { struct rpmtd_s copytd, td; rpmtd utd = &td; Header nh; Header oh; HeaderIterator hi; if (headerGet(*hdrp, tag, utd, HEADERGET_DEFAULT)) { nh = headerNew(); oh = headerCopyLoad(utd->data); hi = headerInitIterator(oh); while (headerNext(hi, ©td)) { if (copytd.data) headerPut(nh, ©td, HEADERPUT_DEFAULT); rpmtdFreeData(©td); } headerFreeIterator(hi); headerFree(oh); rpmtdFreeData(utd); headerFree(*hdrp); *hdrp = headerLink(nh); headerFree(nh); } }
/** * Check that no duplicate tags are present in header. * @param h header * @param NVR package name-version-release * @return RPMRC_OK if OK */ static rpmRC checkForDuplicates(Header h, const char * NVR) /*@globals internalState @*/ /*@modifies h, internalState @*/ { HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); HeaderIterator hi; rpmTag lastTag = 0; rpmRC rc = RPMRC_OK; for (hi = headerInit(h); headerNext(hi, he, 0); he->p.ptr = _free(he->p.ptr)) { if (he->tag != lastTag) { lastTag = he->tag; continue; } rpmlog(RPMLOG_ERR, _("Duplicate %s entries in package: %s\n"), tagName(he->tag), NVR); rc = RPMRC_FAIL; } hi = headerFini(hi); return rc; }
/** * This assumes the order of list matches the order of the new headers, and * throws an exception if that isn't true. */ static int rpmMergeHeaders(PyObject * list, FD_t fd, int matchTag) { Header h; HeaderIterator hi; rpmTagVal newMatch, oldMatch; hdrObject * hdr; rpm_count_t count = 0; int rc = 1; /* assume failure */ rpmtd td = rpmtdNew(); Py_BEGIN_ALLOW_THREADS h = headerRead(fd, HEADER_MAGIC_YES); Py_END_ALLOW_THREADS while (h) { if (!headerGet(h, matchTag, td, HEADERGET_MINMEM)) { PyErr_SetString(pyrpmError, "match tag missing in new header"); goto exit; } newMatch = rpmtdTag(td); rpmtdFreeData(td); hdr = (hdrObject *) PyList_GetItem(list, count++); if (!hdr) goto exit; if (!headerGet(hdr->h, matchTag, td, HEADERGET_MINMEM)) { PyErr_SetString(pyrpmError, "match tag missing in new header"); goto exit; } oldMatch = rpmtdTag(td); rpmtdFreeData(td); if (newMatch != oldMatch) { PyErr_SetString(pyrpmError, "match tag mismatch"); goto exit; } for (hi = headerInitIterator(h); headerNext(hi, td); rpmtdFreeData(td)) { /* could be dupes */ headerDel(hdr->h, rpmtdTag(td)); headerPut(hdr->h, td, HEADERPUT_DEFAULT); } headerFreeIterator(hi); h = headerFree(h); Py_BEGIN_ALLOW_THREADS h = headerRead(fd, HEADER_MAGIC_YES); Py_END_ALLOW_THREADS } rc = 0; exit: rpmtdFree(td); return rc; }
static JSBool rpmhdr_enumerate(JSContext *cx, JSObject *obj, JSIterateOp op, jsval *statep, jsid *idp) { void * ptr = JS_GetInstancePrivate(cx, obj, &rpmhdrClass, NULL); Header h = ptr; HeaderIterator hi = NULL; HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); JSObject *ho = NULL; JSBool ok = JS_FALSE; _ENUMERATE_DEBUG_ENTRY(_debug); switch (op) { case JSENUMERATE_INIT: if ((ho = JS_NewObject(cx, &rpmhiClass, NULL, obj)) == NULL) goto exit; if ((hi = headerInit(h)) == NULL) goto exit; if (!JS_SetPrivate(cx, ho, (void *)hi)) { hi = headerFini(hi); goto exit; } *statep = OBJECT_TO_JSVAL(ho); if (idp) *idp = JSVAL_ZERO; if (_debug) fprintf(stderr, "\tINIT ho %p hi %p\n", ho, hi); break; case JSENUMERATE_NEXT: ho = (JSObject *) JSVAL_TO_OBJECT(*statep); hi = JS_GetInstancePrivate(cx, ho, &rpmhiClass, NULL); if (_debug) fprintf(stderr, "\tNEXT ho %p hi %p\n", ho, hi); if (headerNext(hi, he, 0)) { JS_ValueToId(cx, INT_TO_JSVAL(he->tag), idp); he->p.ptr = _free(he->p.ptr); } else *idp = JSVAL_VOID; if (*idp != JSVAL_VOID) break; /*@fallthrough@*/ case JSENUMERATE_DESTROY: ho = (JSObject *) JSVAL_TO_OBJECT(*statep); hi = JS_GetInstancePrivate(cx, ho, &rpmhiClass, NULL); if (_debug) fprintf(stderr, "\tFINI ho %p hi %p\n", ho, hi); /* Allow our iterator object to be GC'd. */ *statep = JSVAL_NULL; break; } ok = JS_TRUE; exit: return ok; }
static void initSourceHeader(rpmSpec spec) { Package sourcePkg = spec->sourcePackage; struct Source *srcPtr; if (headerIsEntry(sourcePkg->header, RPMTAG_NAME)) return; /* Only specific tags are added to the source package header */ headerCopyTags(spec->packages->header, sourcePkg->header, sourceTags); /* Add the build restrictions */ for (int i=0; i<PACKAGE_NUM_DEPS; i++) { rpmdsPutToHeader(sourcePkg->dependencies[i], sourcePkg->header); } { HeaderIterator hi = headerInitIterator(spec->buildRestrictions); struct rpmtd_s td; while (headerNext(hi, &td)) { if (rpmtdCount(&td) > 0) { (void) headerPut(sourcePkg->header, &td, HEADERPUT_DEFAULT); } rpmtdFreeData(&td); } headerFreeIterator(hi); } if (spec->BANames && spec->BACount > 0) { headerPutStringArray(sourcePkg->header, RPMTAG_BUILDARCHS, spec->BANames, spec->BACount); } /* Add tags for sources and patches */ for (srcPtr = spec->sources; srcPtr != NULL; srcPtr = srcPtr->next) { if (srcPtr->flags & RPMBUILD_ISSOURCE) { headerPutString(sourcePkg->header, RPMTAG_SOURCE, srcPtr->source); if (srcPtr->flags & RPMBUILD_ISNO) { headerPutUint32(sourcePkg->header, RPMTAG_NOSOURCE, &srcPtr->num, 1); } } if (srcPtr->flags & RPMBUILD_ISPATCH) { headerPutString(sourcePkg->header, RPMTAG_PATCH, srcPtr->source); if (srcPtr->flags & RPMBUILD_ISNO) { headerPutUint32(sourcePkg->header, RPMTAG_NOPATCH, &srcPtr->num, 1); } } } }
int headerNextIterator(HeaderIterator hi, rpm_tag_t * tag, rpm_tagtype_t * type, rpm_data_t * p, rpm_count_t * c) { struct rpmtd_s td; int rc; rc = headerNext(hi, &td); if (tag) *tag = td.tag; TDWRAP(); return rc; }
/** \ingroup header * Duplicate a header. * @param h header * @return new header instance */ Header headerCopy(Header h) { Header nh = headerNew(); HeaderIterator hi; struct rpmtd_s td; hi = headerInitIterator(h); while (headerNext(hi, &td)) { if (rpmtdCount(&td) > 0) { (void) headerPut(nh, &td, HEADERPUT_DEFAULT); } rpmtdFreeData(&td); } hi = headerFreeIterator(hi); return headerReload(nh, HEADER_IMAGE); }
Header headerRegenSigHeader(const Header h, int noArchiveSize) { Header sigh = rpmNewSignature(); HeaderIterator hi; struct rpmtd_s td; for (hi = headerInitIterator(h); headerNext(hi, &td); rpmtdFreeData(&td)) { switch (td.tag) { /* XXX Translate legacy signature tag values. */ case RPMTAG_SIGSIZE: td.tag = RPMSIGTAG_SIZE; break; case RPMTAG_SIGPGP: td.tag = RPMSIGTAG_PGP; break; case RPMTAG_SIGMD5: td.tag = RPMSIGTAG_MD5; break; case RPMTAG_SIGGPG: td.tag = RPMSIGTAG_GPG; break; case RPMTAG_SIGPGP5: td.tag = RPMSIGTAG_PGP5; break; case RPMTAG_ARCHIVESIZE: /* XXX rpm-4.1 and later has archive size in signature header. */ if (noArchiveSize) continue; td.tag = RPMSIGTAG_PAYLOADSIZE; break; case RPMTAG_SHA1HEADER: case RPMTAG_DSAHEADER: case RPMTAG_RSAHEADER: default: if (!(td.tag >= HEADER_SIGBASE && td.tag < HEADER_TAGBASE)) continue; break; } if (td.data == NULL) continue; /* XXX can't happen */ if (!headerIsEntry(sigh, td.tag)) (void) headerPut(sigh, &td, HEADERPUT_DEFAULT); } hi = headerFreeIterator(hi); return sigh; }
static int rpmpkgVerifySigs(rpmKeyring keyring, rpmQueryFlags flags, FD_t fd, const char *fn) { char *buf = NULL; char *missingKeys = NULL; char *untrustedKeys = NULL; struct rpmtd_s sigtd; pgpDigParams sig = NULL; Header sigh = NULL; HeaderIterator hi = NULL; char * msg = NULL; int res = 1; /* assume failure */ rpmRC rc; int failed = 0; int nodigests = !(flags & VERIFY_DIGEST); int nosignatures = !(flags & VERIFY_SIGNATURE); struct sigtInfo_s sinfo; rpmDigestBundle plbundle = rpmDigestBundleNew(); rpmDigestBundle hdrbundle = rpmDigestBundleNew(); if ((rc = rpmLeadRead(fd, NULL, NULL, &msg)) != RPMRC_OK) { goto exit; } rc = rpmReadSignature(fd, &sigh, RPMSIGTYPE_HEADERSIG, &msg); if (rc != RPMRC_OK) { goto exit; } /* Initialize all digests we'll be needing */ hi = headerInitIterator(sigh); for (; headerNext(hi, &sigtd) != 0; rpmtdFreeData(&sigtd)) { rc = rpmSigInfoParse(&sigtd, "package", &sinfo, NULL, NULL); if (nosignatures && sinfo.type == RPMSIG_SIGNATURE_TYPE) continue; if (nodigests && sinfo.type == RPMSIG_DIGEST_TYPE) continue; if (rc == RPMRC_OK && sinfo.hashalgo) { rpmDigestBundleAdd(sinfo.payload ? plbundle : hdrbundle, sinfo.hashalgo, RPMDIGEST_NONE); } } hi = headerFreeIterator(hi); /* Read the file, generating digest(s) on the fly. */ fdSetBundle(fd, plbundle); if (readFile(fd, fn, plbundle, hdrbundle)) { goto exit; } rasprintf(&buf, "%s:%c", fn, (rpmIsVerbose() ? '\n' : ' ') ); hi = headerInitIterator(sigh); for (; headerNext(hi, &sigtd) != 0; rpmtdFreeData(&sigtd)) { char *result = NULL; DIGEST_CTX ctx = NULL; if (sigtd.data == NULL) /* XXX can't happen */ continue; /* Clean up parameters from previous sigtag. */ sig = pgpDigParamsFree(sig); /* Note: we permit failures to be ignored via disablers */ rc = rpmSigInfoParse(&sigtd, "package", &sinfo, &sig, &result); if (nosignatures && sinfo.type == RPMSIG_SIGNATURE_TYPE) continue; if (nodigests && sinfo.type == RPMSIG_DIGEST_TYPE) continue; if (sinfo.type == RPMSIG_OTHER_TYPE) continue; if (rc == RPMRC_OK) { ctx = rpmDigestBundleDupCtx(sinfo.payload ? plbundle : hdrbundle, sinfo.hashalgo); rc = rpmVerifySignature(keyring, &sigtd, sig, ctx, &result); rpmDigestFinal(ctx, NULL, NULL, 0); } if (result) { formatResult(sigtd.tag, rc, result, (rc == RPMRC_NOKEY ? &missingKeys : &untrustedKeys), &buf); free(result); } if (rc != RPMRC_OK) { failed = 1; } } res = failed; if (rpmIsVerbose()) { rpmlog(RPMLOG_NOTICE, "%s", buf); } else { const char *ok = (failed ? _("NOT OK") : _("OK")); rpmlog(RPMLOG_NOTICE, "%s%s%s%s%s%s%s%s\n", buf, ok, missingKeys ? _(" (MISSING KEYS:") : "", missingKeys ? missingKeys : "", missingKeys ? _(") ") : "", untrustedKeys ? _(" (UNTRUSTED KEYS:") : "", untrustedKeys ? untrustedKeys : "", untrustedKeys ? _(")") : ""); } free(missingKeys); free(untrustedKeys); exit: if (res && msg != NULL) rpmlog(RPMLOG_ERR, "%s: %s\n", fn, msg); free(msg); free(buf); rpmDigestBundleFree(hdrbundle); rpmDigestBundleFree(plbundle); fdSetBundle(fd, NULL); /* XXX avoid double-free from fd close */ sigh = rpmFreeSignature(sigh); hi = headerFreeIterator(hi); pgpDigParamsFree(sig); return res; }
/** \ingroup header * Translate and merge legacy signature tags into header. * @param h header (dest) * @param sigh signature header (src) */ static void headerMergeLegacySigs(Header h, Header sigh) { HeaderIterator hi; struct rpmtd_s td; hi = headerInitIterator(sigh); for (; headerNext(hi, &td); rpmtdFreeData(&td)) { switch (td.tag) { /* XXX Translate legacy signature tag values. */ case RPMSIGTAG_SIZE: td.tag = RPMTAG_SIGSIZE; break; case RPMSIGTAG_PGP: td.tag = RPMTAG_SIGPGP; break; case RPMSIGTAG_MD5: td.tag = RPMTAG_SIGMD5; break; case RPMSIGTAG_GPG: td.tag = RPMTAG_SIGGPG; break; case RPMSIGTAG_PGP5: td.tag = RPMTAG_SIGPGP5; break; case RPMSIGTAG_PAYLOADSIZE: td.tag = RPMTAG_ARCHIVESIZE; break; case RPMSIGTAG_SHA1: case RPMSIGTAG_DSA: case RPMSIGTAG_RSA: default: if (!(td.tag >= HEADER_SIGBASE && td.tag < HEADER_TAGBASE)) continue; break; } if (!headerIsEntry(h, td.tag)) { switch(td.type) { case RPM_NULL_TYPE: continue; break; case RPM_CHAR_TYPE: case RPM_INT8_TYPE: case RPM_INT16_TYPE: case RPM_INT32_TYPE: case RPM_INT64_TYPE: if (td.count != 1) continue; break; case RPM_STRING_TYPE: case RPM_BIN_TYPE: if (td.count >= 16*1024) continue; break; case RPM_STRING_ARRAY_TYPE: case RPM_I18NSTRING_TYPE: continue; break; } (void) headerPut(h, &td, HEADERPUT_DEFAULT); } } headerFreeIterator(hi); }