Пример #1
0
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, &copytd)) {
	    if (copytd.data)
		headerPut(nh, &copytd, HEADERPUT_DEFAULT);
	    rpmtdFreeData(&copytd);
	}

	headerFreeIterator(hi);
	headerFree(oh);
	rpmtdFreeData(utd);
	headerFree(*hdrp);
	*hdrp = headerLink(nh);
	headerFree(nh);
    }
}
Пример #2
0
static PyObject * hdrKeyList(hdrObject * s)
{
    PyObject * keys;
    HeaderIterator hi;
    rpmTagVal tag;

    keys = PyList_New(0);
    if (!keys) {
        return NULL;
    }

    hi = headerInitIterator(s->h);
    while ((tag = headerNextTag(hi)) != RPMTAG_NOT_FOUND) {
	PyObject *to = PyInt_FromLong(tag);
        if (!to) {
            headerFreeIterator(hi);
            Py_DECREF(keys);
            return NULL;
        }
	PyList_Append(keys, to);
	Py_DECREF(to);
    }
    headerFreeIterator(hi);

    return keys;
}
Пример #3
0
/**
 * 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;
}
Пример #4
0
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);
            }
        }
    }
}
Пример #5
0
static PyObject * hdr_iternext(hdrObject *s)
{
    PyObject *res = NULL;
    rpmTagVal tag;

    if (s->hi == NULL) s->hi = headerInitIterator(s->h);

    if ((tag = headerNextTag(s->hi)) != RPMTAG_NOT_FOUND) {
	res = PyInt_FromLong(tag);
    } else {
	s->hi = headerFreeIterator(s->hi);
    }
    return res;
}
Пример #6
0
/** \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);
}
Пример #7
0
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;
}
Пример #8
0
/**
 * Check that no duplicate tags are present in header.
 * @param h		header
 * @param NVR		package name-version-release
 * @return		RPMRC_OK if OK
 */
static int checkForDuplicates(Header h, const char * NVR)
{
    int res = RPMRC_OK;
    rpmTagVal tag, lastTag = RPMTAG_NOT_FOUND;
    HeaderIterator hi = headerInitIterator(h);

    while ((tag = headerNextTag(hi)) != RPMTAG_NOT_FOUND) {
	if (tag == lastTag) {
	    rpmlog(RPMLOG_ERR, _("Duplicate %s entries in package: %s\n"),
		     rpmTagGetName(tag), NVR);
	    res = RPMRC_FAIL;
	}
	lastTag = tag;
    }
    headerFreeIterator(hi);

    return res;
}
Пример #9
0
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;
}
Пример #10
0
rpmRC checkForEncoding(Header h, int addtag)
{
    rpmRC rc = RPMRC_OK;
#if HAVE_ICONV
    const char *encoding = "utf-8";
    rpmTagVal tag;
    iconv_t ic = (iconv_t) -1;
    char *dest = NULL;
    size_t destlen = 0;
    int strict = rpmExpandNumeric("%{_invalid_encoding_terminates_build}");
    HeaderIterator hi = headerInitIterator(h);

    ic = iconv_open(encoding, encoding);
    if (ic == (iconv_t) -1) {
        rpmlog(RPMLOG_WARNING,
               _("encoding %s not supported by system\n"), encoding);
        goto exit;
    }

    while ((tag = headerNextTag(hi)) != RPMTAG_NOT_FOUND) {
        struct rpmtd_s td;
        const char *src = NULL;

        if (rpmTagGetClass(tag) != RPM_STRING_CLASS)
            continue;

        headerGet(h, tag, &td, (HEADERGET_RAW|HEADERGET_MINMEM));
        while ((src = rpmtdNextString(&td)) != NULL) {
            size_t srclen = strlen(src);
            size_t outlen, inlen = srclen;
            char *out, *in = (char *) src;

            if (destlen < srclen) {
                destlen = srclen * 2;
                dest = xrealloc(dest, destlen);
            }
            out = dest;
            outlen = destlen;

            /* reset conversion state */
            iconv(ic, NULL, &inlen, &out, &outlen);

            if (iconv(ic, &in, &inlen, &out, &outlen) == (size_t) -1) {
                rpmlog(strict ? RPMLOG_ERR : RPMLOG_WARNING,
                       _("Package %s: invalid %s encoding in %s: %s - %s\n"),
                       headerGetString(h, RPMTAG_NAME),
                       encoding, rpmTagGetName(tag), src, strerror(errno));
                rc = RPMRC_FAIL;
            }

        }
        rpmtdFreeData(&td);
    }

    /* Stomp "known good utf" mark in header if requested */
    if (rc == RPMRC_OK && addtag)
        headerPutString(h, RPMTAG_ENCODING, encoding);
    if (!strict)
        rc = RPMRC_OK;

exit:
    if (ic != (iconv_t) -1)
        iconv_close(ic);
    headerFreeIterator(hi);
    free(dest);
#endif /* HAVE_ICONV */

    return rc;
}
Пример #11
0
/** \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);
}