Esempio n. 1
0
/**
 * Print package size (debug purposes only)
 * @param fd			package file handle
 * @param sigh			signature header
 */
static void printSize(FD_t fd, Header sigh)
{
    struct stat st;
    int fdno = Fileno(fd);
    size_t siglen = headerSizeof(sigh, HEADER_MAGIC_YES);
    size_t pad = (8 - (siglen % 8)) % 8; /* 8-byte pad */
    struct rpmtd_s sizetag;
    rpm_loff_t datalen = 0;

    /* Print package component sizes. */
    if (headerGet(sigh, RPMSIGTAG_LONGSIZE, &sizetag, HEADERGET_DEFAULT)) {
	rpm_loff_t *tsize = rpmtdGetUint64(&sizetag);
	datalen = (tsize) ? *tsize : 0;
    } else if (headerGet(sigh, RPMSIGTAG_SIZE, &sizetag, HEADERGET_DEFAULT)) {
	rpm_off_t *tsize = rpmtdGetUint32(&sizetag);
	datalen = (tsize) ? *tsize : 0;
    }
    rpmtdFreeData(&sizetag);

    rpmlog(RPMLOG_DEBUG,
		"Expected size: %12" PRIu64 \
		" = lead(%d)+sigs(%zd)+pad(%zd)+data(%" PRIu64 ")\n",
		RPMLEAD_SIZE+siglen+pad+datalen,
		RPMLEAD_SIZE, siglen, pad, datalen);

    if (fstat(fdno, &st) == 0) {
	rpmlog(RPMLOG_DEBUG,
		"  Actual size: %12" PRIu64 "\n", (rpm_loff_t) st.st_size);
    }
}
Esempio n. 2
0
/*
 * Convert single tag data item to python object of suitable type
 */
PyObject * rpmtd_ItemAsPyobj(rpmtd td)
{
    PyObject *res = NULL;
    char *str = NULL;

    switch (rpmtdType(td)) {
    case RPM_STRING_TYPE:
    case RPM_I18NSTRING_TYPE:
    case RPM_STRING_ARRAY_TYPE:
	res = PyString_FromString(rpmtdGetString(td));
	break;
    case RPM_INT64_TYPE:
	res = PyLong_FromLongLong(*rpmtdGetUint64(td));
	break;
    case RPM_INT32_TYPE:
	res = PyInt_FromLong(*rpmtdGetUint32(td));
	break;
    case RPM_INT16_TYPE:
	res = PyInt_FromLong(*rpmtdGetUint16(td));
	break;
    case RPM_BIN_TYPE:
	str = rpmtdFormat(td, RPMTD_FORMAT_STRING, NULL);
	res = PyString_FromString(str);
	free(str);
	break;
    default:
	PyErr_SetString(PyExc_KeyError, "unhandled data type");
	break;
    }
    return res;
}
Esempio n. 3
0
File: rpmtd.c Progetto: akozumpl/rpm
uint64_t *rpmtdNextUint64(rpmtd td)
{
    assert(td != NULL);
    uint64_t *res = NULL;
    if (rpmtdNext(td) >= 0) {
	res = rpmtdGetUint64(td);
    }
    return res;
}
Esempio n. 4
0
rpmRC rpmReadSignature(FD_t fd, Header * sighp, sigType sig_type, char ** msg)
{
    char *buf = NULL;
    int32_t block[4];
    int32_t il;
    int32_t dl;
    int32_t * ei = NULL;
    entryInfo pe;
    unsigned int nb, uc;
    int32_t ril = 0;
    struct indexEntry_s entry;
    struct entryInfo_s info;
    unsigned char * dataStart;
    unsigned char * dataEnd = NULL;
    Header sigh = NULL;
    rpmRC rc = RPMRC_FAIL;		/* assume failure */
    int xx;
    int i;

    if (sighp)
	*sighp = NULL;

    if (sig_type != RPMSIGTYPE_HEADERSIG)
	goto exit;

    memset(block, 0, sizeof(block));
    if ((xx = Fread(block, 1, sizeof(block), fd)) != sizeof(block)) {
	rasprintf(&buf, _("sigh size(%d): BAD, read returned %d\n"), 
		  (int)sizeof(block), xx);
	goto exit;
    }
    if (memcmp(block, rpm_header_magic, sizeof(rpm_header_magic))) {
	rasprintf(&buf, _("sigh magic: BAD\n"));
	goto exit;
    }
    il = ntohl(block[2]);
    if (il < 0 || il > 32) {
	rasprintf(&buf, 
		  _("sigh tags: BAD, no. of tags(%d) out of range\n"), il);
	goto exit;
    }
    dl = ntohl(block[3]);
    if (dl < 0 || dl > 8192) {
	rasprintf(&buf, 
		  _("sigh data: BAD, no. of  bytes(%d) out of range\n"), dl);
	goto exit;
    }

    memset(&entry, 0, sizeof(entry));
    memset(&info, 0, sizeof(info));

    nb = (il * sizeof(struct entryInfo_s)) + dl;
    uc = sizeof(il) + sizeof(dl) + nb;
    ei = xmalloc(uc);
    ei[0] = block[2];
    ei[1] = block[3];
    pe = (entryInfo) &ei[2];
    dataStart = (unsigned char *) (pe + il);
    if ((xx = Fread(pe, 1, nb, fd)) != nb) {
	rasprintf(&buf,
		  _("sigh blob(%d): BAD, read returned %d\n"), (int)nb, xx);
	goto exit;
    }
    
    /* Check (and convert) the 1st tag element. */
    xx = headerVerifyInfo(1, dl, pe, &entry.info, 0);
    if (xx != -1) {
	rasprintf(&buf, _("tag[%d]: BAD, tag %d type %d offset %d count %d\n"),
		  0, entry.info.tag, entry.info.type,
		  entry.info.offset, entry.info.count);
	goto exit;
    }

    /* Is there an immutable header region tag? */
    if (entry.info.tag == RPMTAG_HEADERSIGNATURES) {
	/* Is the region tag sane? */
	if (!(entry.info.type == REGION_TAG_TYPE &&
	      entry.info.count == REGION_TAG_COUNT)) {
	    rasprintf(&buf,
		_("region tag: BAD, tag %d type %d offset %d count %d\n"),
		entry.info.tag, entry.info.type,
		entry.info.offset, entry.info.count);
	    goto exit;
	}
	
	/* Is the trailer within the data area? */
	if (entry.info.offset + REGION_TAG_COUNT > dl) {
	    rasprintf(&buf, 
		_("region offset: BAD, tag %d type %d offset %d count %d\n"),
		entry.info.tag, entry.info.type,
		entry.info.offset, entry.info.count);
	    goto exit;
	}

	/* Is there an immutable header region tag trailer? */
	dataEnd = dataStart + entry.info.offset;
	(void) memcpy(&info, dataEnd, REGION_TAG_COUNT);
	/* XXX Really old packages have HEADER_IMAGE, not HEADER_SIGNATURES. */
	if (info.tag == htonl(RPMTAG_HEADERIMAGE)) {
	    rpmTagVal stag = htonl(RPMTAG_HEADERSIGNATURES);
	    info.tag = stag;
	    memcpy(dataEnd, &stag, sizeof(stag));
	}
	dataEnd += REGION_TAG_COUNT;

	xx = headerVerifyInfo(1, il * sizeof(*pe), &info, &entry.info, 1);
	if (xx != -1 ||
	    !((entry.info.tag == RPMTAG_HEADERSIGNATURES || entry.info.tag == RPMTAG_HEADERIMAGE)
	   && entry.info.type == REGION_TAG_TYPE
	   && entry.info.count == REGION_TAG_COUNT))
	{
	    rasprintf(&buf,
		_("region trailer: BAD, tag %d type %d offset %d count %d\n"),
		entry.info.tag, entry.info.type,
		entry.info.offset, entry.info.count);
	    goto exit;
	}
	memset(&info, 0, sizeof(info));

	/* Is the no. of tags in the region less than the total no. of tags? */
	ril = entry.info.offset/sizeof(*pe);
	if ((entry.info.offset % sizeof(*pe)) || ril > il) {
	    rasprintf(&buf, _("region size: BAD, ril(%d) > il(%d)\n"), ril, il);
	    goto exit;
	}
    }

    /* Sanity check signature tags */
    memset(&info, 0, sizeof(info));
    for (i = 1; i < il; i++) {
	xx = headerVerifyInfo(1, dl, pe+i, &entry.info, 0);
	if (xx != -1) {
	    rasprintf(&buf, 
		_("sigh tag[%d]: BAD, tag %d type %d offset %d count %d\n"),
		i, entry.info.tag, entry.info.type,
		entry.info.offset, entry.info.count);
	    goto exit;
	}
    }

    /* OK, blob looks sane, load the header. */
    sigh = headerImport(ei, uc, 0);
    if (sigh == NULL) {
	rasprintf(&buf, _("sigh load: BAD\n"));
	goto exit;
    }

    {	size_t sigSize = headerSizeof(sigh, HEADER_MAGIC_YES);
	size_t pad = (8 - (sigSize % 8)) % 8; /* 8-byte pad */
	ssize_t trc;
	struct rpmtd_s sizetag;
	rpm_loff_t archSize = 0;

	/* Position at beginning of header. */
	if (pad && (trc = Fread(block, 1, pad, fd)) != pad) {
	    rasprintf(&buf,
		      _("sigh pad(%zd): BAD, read %zd bytes\n"), pad, trc);
	    goto exit;
	}

	/* Print package component sizes. */
	if (headerGet(sigh, RPMSIGTAG_LONGSIZE, &sizetag, HEADERGET_DEFAULT)) {
	    rpm_loff_t *tsize = rpmtdGetUint64(&sizetag);
	    archSize = (tsize) ? *tsize : 0;
	} else if (headerGet(sigh, RPMSIGTAG_SIZE, &sizetag, HEADERGET_DEFAULT)) {
	    rpm_off_t *tsize = rpmtdGetUint32(&sizetag);
	    archSize = (tsize) ? *tsize : 0;
	}
	rpmtdFreeData(&sizetag);
	rc = printSize(fd, sigSize, pad, archSize);
	if (rc != RPMRC_OK) {
	    rasprintf(&buf,
		   _("sigh sigSize(%zd): BAD, fstat(2) failed\n"), sigSize);
	    goto exit;
	}
    }
    ei = NULL; /* XXX will be freed with header */

exit:
    if (sighp && sigh && rc == RPMRC_OK)
	*sighp = headerLink(sigh);
    headerFree(sigh);
    free(ei);

    if (msg != NULL) {
	*msg = buf;
    } else {
	free(buf);
    }

    return rc;
}
Esempio n. 5
0
rpmfi rpmfiNew(const rpmts ts, Header h, rpmTag tagN, rpmfiFlags flags)
{
    rpmfi fi = NULL;
    rpm_loff_t *asize = NULL;
    unsigned char * t;
    int isBuild, isSource;
    struct rpmtd_s fdigests, digalgo;
    struct rpmtd_s td;
    headerGetFlags scareFlags = (flags & RPMFI_KEEPHEADER) ? 
				HEADERGET_MINMEM : HEADERGET_ALLOC;
    headerGetFlags defFlags = HEADERGET_ALLOC;

    fi = xcalloc(1, sizeof(*fi));
    if (fi == NULL)	/* XXX can't happen */
	goto exit;

    fi->magic = RPMFIMAGIC;
    fi->i = -1;

    fi->fiflags = flags;
    fi->scareFlags = scareFlags;

    if (headerGet(h, RPMTAG_LONGARCHIVESIZE, &td, HEADERGET_EXT)) {
	asize = rpmtdGetUint64(&td);
    }
    /* 0 means unknown */
    fi->archiveSize = asize ? *asize : 0;
    rpmtdFreeData(&td);
    
    /* Archive size is not set when this gets called from build */
    isBuild = (asize == NULL);
    isSource = headerIsSource(h);
    if (isBuild) fi->fiflags |= RPMFI_ISBUILD;
    if (isSource) fi->fiflags |= RPMFI_ISSOURCE;

    _hgfi(h, RPMTAG_BASENAMES, &td, defFlags, fi->bnl);
    fi->fc = rpmtdCount(&td);
    if (fi->fc == 0) {
	goto exit;
    }

    _hgfi(h, RPMTAG_DIRNAMES, &td, defFlags, fi->dnl);
    fi->dc = rpmtdCount(&td);
    _hgfi(h, RPMTAG_DIRINDEXES, &td, scareFlags, fi->dil);
    if (!(flags & RPMFI_NOFILEMODES))
	_hgfi(h, RPMTAG_FILEMODES, &td, scareFlags, fi->fmodes);
    if (!(flags & RPMFI_NOFILEFLAGS))
	_hgfi(h, RPMTAG_FILEFLAGS, &td, scareFlags, fi->fflags);
    if (!(flags & RPMFI_NOFILEVERIFYFLAGS))
	_hgfi(h, RPMTAG_FILEVERIFYFLAGS, &td, scareFlags, fi->vflags);
    if (!(flags & RPMFI_NOFILESIZES))
	_hgfi(h, RPMTAG_FILESIZES, &td, scareFlags, fi->fsizes);

    if (!(flags & RPMFI_NOFILECOLORS))
	_hgfi(h, RPMTAG_FILECOLORS, &td, scareFlags, fi->fcolors);

    if (!(flags & RPMFI_NOFILECLASS)) {
	_hgfi(h, RPMTAG_CLASSDICT, &td, scareFlags, fi->cdict);
	fi->ncdict = rpmtdCount(&td);
	_hgfi(h, RPMTAG_FILECLASS, &td, scareFlags, fi->fcdictx);
    }
    if (!(flags & RPMFI_NOFILEDEPS)) {
	_hgfi(h, RPMTAG_DEPENDSDICT, &td, scareFlags, fi->ddict);
	fi->nddict = rpmtdCount(&td);
	_hgfi(h, RPMTAG_FILEDEPENDSX, &td, scareFlags, fi->fddictx);
	_hgfi(h, RPMTAG_FILEDEPENDSN, &td, scareFlags, fi->fddictn);
    }

    if (!(flags & RPMFI_NOFILESTATES))
	_hgfi(h, RPMTAG_FILESTATES, &td, defFlags, fi->fstates);

    if (!(flags & RPMFI_NOFILECAPS) && headerIsEntry(h, RPMTAG_FILECAPS)) {
	fi->fcapcache = strcacheNew();
	fi->fcaps = cacheTag(fi->fcapcache, h, RPMTAG_FILECAPS);
    }

    if (!(flags & RPMFI_NOFILELINKTOS)) {
	fi->flinkcache = strcacheNew();
	fi->flinks = cacheTag(fi->flinkcache, h, RPMTAG_FILELINKTOS);
    }
    /* FILELANGS are only interesting when installing */
    if ((headerGetInstance(h) == 0) && !(flags & RPMFI_NOFILELANGS))
	fi->flangs = cacheTag(langcache, h, RPMTAG_FILELANGS);

    /* See if the package has non-md5 file digests */
    fi->digestalgo = PGPHASHALGO_MD5;
    if (headerGet(h, RPMTAG_FILEDIGESTALGO, &digalgo, HEADERGET_MINMEM)) {
	pgpHashAlgo *algo = rpmtdGetUint32(&digalgo);
	/* Hmm, what to do with unknown digest algorithms? */
	if (algo && rpmDigestLength(*algo) != 0) {
	    fi->digestalgo = *algo;
	}
    }

    fi->digests = NULL;
    /* grab hex digests from header and store in binary format */
    if (!(flags & RPMFI_NOFILEDIGESTS) &&
	headerGet(h, RPMTAG_FILEDIGESTS, &fdigests, HEADERGET_MINMEM)) {
	const char *fdigest;
	size_t diglen = rpmDigestLength(fi->digestalgo);
	fi->digests = t = xmalloc(rpmtdCount(&fdigests) * diglen);

	while ((fdigest = rpmtdNextString(&fdigests))) {
	    if (!(fdigest && *fdigest != '\0')) {
		memset(t, 0, diglen);
		t += diglen;
		continue;
	    }
	    for (int j = 0; j < diglen; j++, t++, fdigest += 2)
		*t = (rnibble(fdigest[0]) << 4) | rnibble(fdigest[1]);
	}
	rpmtdFreeData(&fdigests);
    }

    /* XXX TR_REMOVED doesn;t need fmtimes, frdevs, finodes */
    if (!(flags & RPMFI_NOFILEMTIMES))
	_hgfi(h, RPMTAG_FILEMTIMES, &td, scareFlags, fi->fmtimes);
    if (!(flags & RPMFI_NOFILERDEVS))
	_hgfi(h, RPMTAG_FILERDEVS, &td, scareFlags, fi->frdevs);
    if (!(flags & RPMFI_NOFILEINODES))
	_hgfi(h, RPMTAG_FILEINODES, &td, scareFlags, fi->finodes);

    if (!(flags & RPMFI_NOFILEUSER)) 
	fi->fuser = cacheTag(ugcache, h, RPMTAG_FILEUSERNAME);
    if (!(flags & RPMFI_NOFILEGROUP)) 
	fi->fgroup = cacheTag(ugcache, h, RPMTAG_FILEGROUPNAME);

    /* lazily alloced from rpmfiFN() */
    fi->fn = NULL;

exit:
if (_rpmfi_debug < 0)
fprintf(stderr, "*** fi %p\t[%d]\n", fi, (fi ? fi->fc : 0));

    if (fi != NULL) {
	fi->h = (fi->fiflags & RPMFI_KEEPHEADER) ? headerLink(h) : NULL;
    }

    /* FIX: rpmfi null annotations */
    return rpmfiLink(fi, __FUNCTION__);
}
Esempio n. 6
0
File: signature.c Progetto: soig/rpm
rpmRC rpmReadSignature(FD_t fd, Header * sighp, sigType sig_type, char ** msg)
{
    char *buf = NULL;
    int32_t block[4];
    int32_t il;
    int32_t dl;
    int32_t * ei = NULL;
    entryInfo pe;
    unsigned int nb, uc;
    struct indexEntry_s entry;
    unsigned char * dataStart;
    Header sigh = NULL;
    rpmRC rc = RPMRC_FAIL;		/* assume failure */
    int xx;
    int i;

    if (sighp)
        *sighp = NULL;

    if (sig_type != RPMSIGTYPE_HEADERSIG)
        goto exit;

    memset(block, 0, sizeof(block));
    if ((xx = Freadall(fd, block, sizeof(block))) != sizeof(block)) {
        rasprintf(&buf, _("sigh size(%d): BAD, read returned %d"),
                  (int)sizeof(block), xx);
        goto exit;
    }
    if (memcmp(block, rpm_header_magic, sizeof(rpm_header_magic))) {
        rasprintf(&buf, _("sigh magic: BAD"));
        goto exit;
    }
    il = ntohl(block[2]);
    if (il < 0 || il > 32) {
        rasprintf(&buf,
                  _("sigh tags: BAD, no. of tags(%d) out of range"), il);
        goto exit;
    }
    dl = ntohl(block[3]);
    if (dl < 0 || dl > 8192) {
        rasprintf(&buf,
                  _("sigh data: BAD, no. of  bytes(%d) out of range"), dl);
        goto exit;
    }

    memset(&entry, 0, sizeof(entry));

    nb = (il * sizeof(struct entryInfo_s)) + dl;
    uc = sizeof(il) + sizeof(dl) + nb;
    ei = xmalloc(uc);
    ei[0] = block[2];
    ei[1] = block[3];
    pe = (entryInfo) &ei[2];
    dataStart = (unsigned char *) (pe + il);
    if ((xx = Freadall(fd, pe, nb)) != nb) {
        rasprintf(&buf,
                  _("sigh blob(%d): BAD, read returned %d"), (int)nb, xx);
        goto exit;
    }

    /* Verify header immutable region if there is one */
    xx = headerVerifyRegion(RPMTAG_HEADERSIGNATURES,
                            &entry, il, dl, pe, dataStart,
                            NULL, NULL, &buf);
    /* Not found means a legacy V3 package with no immutable region */
    if (xx != RPMRC_OK && xx != RPMRC_NOTFOUND)
        goto exit;

    /* Sanity check signature tags */
    for (i = 1; i < il; i++) {
        xx = headerVerifyInfo(1, dl, pe+i, &entry.info, 0);
        if (xx != -1) {
            rasprintf(&buf,
                      _("sigh tag[%d]: BAD, tag %d type %d offset %d count %d"),
                      i, entry.info.tag, entry.info.type,
                      entry.info.offset, entry.info.count);
            goto exit;
        }
    }

    /* OK, blob looks sane, load the header. */
    sigh = headerImport(ei, uc, 0);
    if (sigh == NULL) {
        rasprintf(&buf, _("sigh load: BAD"));
        goto exit;
    }
    ei = NULL; /* XXX will be freed with header */

    {   size_t sigSize = headerSizeof(sigh, HEADER_MAGIC_YES);
        size_t pad = (8 - (sigSize % 8)) % 8; /* 8-byte pad */
        ssize_t trc;
        struct rpmtd_s sizetag;
        rpm_loff_t archSize = 0;

        /* Position at beginning of header. */
        if (pad && (trc = Freadall(fd, block, pad)) != pad) {
            rasprintf(&buf,
                      _("sigh pad(%zd): BAD, read %zd bytes"), pad, trc);
            goto exit;
        }

        /* Print package component sizes. */
        if (headerGet(sigh, RPMSIGTAG_LONGSIZE, &sizetag, HEADERGET_DEFAULT)) {
            rpm_loff_t *tsize = rpmtdGetUint64(&sizetag);
            archSize = (tsize) ? *tsize : 0;
        } else if (headerGet(sigh, RPMSIGTAG_SIZE, &sizetag, HEADERGET_DEFAULT)) {
            rpm_off_t *tsize = rpmtdGetUint32(&sizetag);
            archSize = (tsize) ? *tsize : 0;
        }
        rpmtdFreeData(&sizetag);
        rc = printSize(fd, sigSize, pad, archSize);
        if (rc != RPMRC_OK) {
            rasprintf(&buf,
                      _("sigh sigSize(%zd): BAD, fstat(2) failed"), sigSize);
            goto exit;
        }
    }

exit:
    if (sighp && sigh && rc == RPMRC_OK)
        *sighp = headerLink(sigh);
    headerFree(sigh);
    free(ei);

    if (msg != NULL) {
        *msg = buf;
    } else {
        free(buf);
    }

    return rc;
}