7 #include <netinet/in.h>
9 #include <rpm/rpmlib.h> /* XXX RPMSIGTAG, other sig stuff */
10 #include <rpm/rpmts.h>
11 #include <rpm/rpmlog.h>
13 #include "lib/legacy.h" /* XXX legacyRetrofit() */
14 #include "lib/rpmlead.h"
15 #include "lib/signature.h"
16 #include "rpmio/digest.h"
17 #include "rpmio/rpmio_internal.h" /* fd*Digest(), fd stats */
18 #include "rpmdb/header_internal.h" /* XXX headerCheck */
22 #define alloca_strdup(_s) strcpy(alloca(strlen(_s)+1), (_s))
24 static int _print_pkts = 0;
26 static unsigned int nkeyids_max = 256;
27 static unsigned int nkeyids = 0;
28 static unsigned int nextkeyid = 0;
29 static unsigned int * keyids;
31 /* XXX FIXME: these are doubled here and header.c and .. */
32 static unsigned char const header_magic[8] = {
33 0x8e, 0xad, 0xe8, 0x01, 0x00, 0x00, 0x00, 0x00
37 * Alignment needs (and sizeof scalars types) for internal rpm data types.
39 static int const typeAlign[16] = {
40 1, /*!< RPM_NULL_TYPE */
41 1, /*!< RPM_CHAR_TYPE */
42 1, /*!< RPM_INT8_TYPE */
43 2, /*!< RPM_INT16_TYPE */
44 4, /*!< RPM_INT32_TYPE */
45 8, /*!< RPM_INT64_TYPE */
46 1, /*!< RPM_STRING_TYPE */
47 1, /*!< RPM_BIN_TYPE */
48 1, /*!< RPM_STRING_ARRAY_TYPE */
49 1, /*!< RPM_I18NSTRING_TYPE */
59 * Sanity check on no. of tags.
60 * This check imposes a limit of 65K tags, more than enough.
62 #define hdrchkTags(_ntags) ((_ntags) & 0xffff0000)
65 * Sanity check on type values.
67 #define hdrchkType(_type) ((_type) < RPM_MIN_TYPE || (_type) > RPM_MAX_TYPE)
70 * Sanity check on data size and/or offset and/or count.
71 * This check imposes a limit of 16 MB, more than enough.
73 #define hdrchkData(_nbytes) ((_nbytes) & 0xff000000)
76 * Sanity check on data alignment for data type.
78 #define hdrchkAlign(_type, _off) ((_off) & (typeAlign[_type]-1))
81 * Sanity check on range of data offset.
83 #define hdrchkRange(_dl, _off) ((_off) < 0 || (_off) > (_dl))
85 void headerMergeLegacySigs(Header h, const Header sigh)
87 HFD_t hfd = (HFD_t) headerFreeData;
88 HAE_t hae = (HAE_t) headerAddEntry;
96 for (hi = headerInitIterator(sigh);
97 headerNextIterator(hi, &tag, &type, &ptr, &count);
101 /* XXX Translate legacy signature tag values. */
103 tag = RPMTAG_SIGSIZE;
105 case RPMSIGTAG_LEMD5_1:
106 tag = RPMTAG_SIGLEMD5_1;
111 case RPMSIGTAG_LEMD5_2:
112 tag = RPMTAG_SIGLEMD5_2;
121 tag = RPMTAG_SIGPGP5;
123 case RPMSIGTAG_PAYLOADSIZE:
124 tag = RPMTAG_ARCHIVESIZE;
130 if (!(tag >= HEADER_SIGBASE && tag < HEADER_TAGBASE))
134 if (ptr == NULL) continue; /* XXX can't happen */
135 if (!headerIsEntry(h, tag)) {
136 if (hdrchkType(type))
138 if (count < 0 || hdrchkData(count))
151 case RPM_STRING_TYPE:
153 if (count >= 16*1024)
156 case RPM_STRING_ARRAY_TYPE:
157 case RPM_I18NSTRING_TYPE:
161 xx = hae(h, tag, type, ptr, count);
164 hi = headerFreeIterator(hi);
167 Header headerRegenSigHeader(const Header h, int noArchiveSize)
169 HFD_t hfd = (HFD_t) headerFreeData;
170 Header sigh = rpmNewSignature();
178 for (hi = headerInitIterator(h);
179 headerNextIterator(hi, &tag, &type, &ptr, &count);
180 ptr = hfd(ptr, type))
183 /* XXX Translate legacy signature tag values. */
185 stag = RPMSIGTAG_SIZE;
187 case RPMTAG_SIGLEMD5_1:
188 stag = RPMSIGTAG_LEMD5_1;
191 stag = RPMSIGTAG_PGP;
193 case RPMTAG_SIGLEMD5_2:
194 stag = RPMSIGTAG_LEMD5_2;
197 stag = RPMSIGTAG_MD5;
200 stag = RPMSIGTAG_GPG;
203 stag = RPMSIGTAG_PGP5;
205 case RPMTAG_ARCHIVESIZE:
206 /* XXX rpm-4.1 and later has archive size in signature header. */
209 stag = RPMSIGTAG_PAYLOADSIZE;
211 case RPMTAG_SHA1HEADER:
212 case RPMTAG_DSAHEADER:
213 case RPMTAG_RSAHEADER:
215 if (!(tag >= HEADER_SIGBASE && tag < HEADER_TAGBASE))
220 if (ptr == NULL) continue; /* XXX can't happen */
221 if (!headerIsEntry(sigh, stag))
222 xx = headerAddEntry(sigh, stag, type, ptr, count);
224 hi = headerFreeIterator(hi);
229 * Remember current key id.
230 * @param ts transaction set
231 * @return 0 if new keyid, otherwise 1
233 static int rpmtsStashKeyid(rpmts ts)
235 const void * sig = rpmtsSig(ts);
236 pgpDig dig = rpmtsDig(ts);
237 pgpDigParams sigp = rpmtsSignature(ts);
241 if (sig == NULL || dig == NULL || sigp == NULL)
244 keyid = pgpGrab(sigp->signid+4, 4);
249 for (i = 0; i < nkeyids; i++) {
250 if (keyid == keyids[i])
254 if (nkeyids < nkeyids_max) {
256 keyids = xrealloc(keyids, nkeyids * sizeof(*keyids));
258 if (keyids) /* XXX can't happen */
259 keyids[nextkeyid] = keyid;
261 nextkeyid %= nkeyids_max;
266 int headerVerifyInfo(int il, int dl, const void * pev, void * iv, int negate)
268 entryInfo pe = (entryInfo) pev;
272 for (i = 0; i < il; i++) {
273 info->tag = ntohl(pe[i].tag);
274 info->type = ntohl(pe[i].type);
275 info->offset = ntohl(pe[i].offset);
277 info->offset = -info->offset;
278 info->count = ntohl(pe[i].count);
280 if (hdrchkType(info->type))
282 if (hdrchkAlign(info->type, info->offset))
284 if (!negate && hdrchkRange(dl, info->offset))
286 if (hdrchkData(info->count))
294 * Check header consistency, performing headerGetEntry() the hard way.
296 * Sanity checks on the header are performed while looking for a
297 * header-only digest or signature to verify the blob. If found,
298 * the digest or signature is verified.
300 * @param ts transaction set
301 * @param uh unloaded header blob
302 * @param uc no. of bytes in blob (or 0 to disable)
303 * @retval *msg signature verification msg
304 * @return RPMRC_OK/RPMRC_NOTFOUND/RPMRC_FAIL
306 rpmRC headerCheck(rpmts ts, const void * uh, size_t uc, char ** msg)
310 int32_t * ei = (int32_t *) uh;
311 int32_t il = ntohl(ei[0]);
312 int32_t dl = ntohl(ei[1]);
313 entryInfo pe = (entryInfo) &ei[2];
315 int32_t pvlen = sizeof(ildl) + (il * sizeof(*pe)) + dl;
316 unsigned char * dataStart = (unsigned char *) (pe + il);
317 indexEntry entry = memset(alloca(sizeof(*entry)), 0, sizeof(*entry));
318 entryInfo info = memset(alloca(sizeof(*info)), 0, sizeof(*info));
320 unsigned const char * b;
321 rpmVSFlags vsflags = rpmtsVSFlags(ts);
326 unsigned char * regionEnd = NULL;
327 rpmRC rc = RPMRC_FAIL; /* assume failure */
335 /* Is the blob the right size? */
336 if (uc > 0 && pvlen != uc) {
337 (void) snprintf(buf, sizeof(buf),
338 _("blob size(%d): BAD, 8 + 16 * il(%d) + dl(%d)\n"),
339 (int)uc, (int)il, (int)dl);
343 /* Check (and convert) the 1st tag element. */
344 xx = headerVerifyInfo(1, dl, pe, &entry->info, 0);
346 (void) snprintf(buf, sizeof(buf),
347 _("tag[%d]: BAD, tag %d type %d offset %d count %d\n"),
348 0, entry->info.tag, entry->info.type,
349 entry->info.offset, entry->info.count);
353 /* Is there an immutable header region tag? */
354 if (!(entry->info.tag == RPMTAG_HEADERIMMUTABLE
355 && entry->info.type == RPM_BIN_TYPE
356 && entry->info.count == REGION_TAG_COUNT))
362 /* Is the offset within the data area? */
363 if (entry->info.offset >= dl) {
364 (void) snprintf(buf, sizeof(buf),
365 _("region offset: BAD, tag %d type %d offset %d count %d\n"),
366 entry->info.tag, entry->info.type,
367 entry->info.offset, entry->info.count);
371 /* Is there an immutable header region tag trailer? */
372 regionEnd = dataStart + entry->info.offset;
373 (void) memcpy(info, regionEnd, REGION_TAG_COUNT);
374 regionEnd += REGION_TAG_COUNT;
376 xx = headerVerifyInfo(1, dl, info, &entry->info, 1);
378 !(entry->info.tag == RPMTAG_HEADERIMMUTABLE
379 && entry->info.type == RPM_BIN_TYPE
380 && entry->info.count == REGION_TAG_COUNT))
382 (void) snprintf(buf, sizeof(buf),
383 _("region trailer: BAD, tag %d type %d offset %d count %d\n"),
384 entry->info.tag, entry->info.type,
385 entry->info.offset, entry->info.count);
388 memset(info, 0, sizeof(*info));
390 /* Is the no. of tags in the region less than the total no. of tags? */
391 ril = entry->info.offset/sizeof(*pe);
392 if ((entry->info.offset % sizeof(*pe)) || ril > il) {
393 (void) snprintf(buf, sizeof(buf),
394 _("region size: BAD, ril(%d) > il(%d)\n"), ril, il);
398 /* Find a header-only digest/signature tag. */
399 for (i = ril; i < il; i++) {
400 xx = headerVerifyInfo(1, dl, pe+i, &entry->info, 0);
402 (void) snprintf(buf, sizeof(buf),
403 _("tag[%d]: BAD, tag %d type %d offset %d count %d\n"),
404 i, entry->info.tag, entry->info.type,
405 entry->info.offset, entry->info.count);
409 switch (entry->info.tag) {
410 case RPMTAG_SHA1HEADER:
411 if (vsflags & RPMVSF_NOSHA1HEADER)
414 for (b = dataStart + entry->info.offset; *b != '\0'; b++) {
415 if (strchr("0123456789abcdefABCDEF", *b) == NULL)
419 if (entry->info.type != RPM_STRING_TYPE || *b != '\0' || blen != 40)
421 (void) snprintf(buf, sizeof(buf), _("hdr SHA1: BAD, not hex\n"));
424 if (info->tag == 0) {
425 *info = entry->info; /* structure assignment */
429 case RPMTAG_RSAHEADER:
430 if (vsflags & RPMVSF_NORSAHEADER)
432 if (entry->info.type != RPM_BIN_TYPE) {
433 (void) snprintf(buf, sizeof(buf), _("hdr RSA: BAD, not binary\n"));
436 *info = entry->info; /* structure assignment */
437 siglen = info->count;
439 case RPMTAG_DSAHEADER:
440 if (vsflags & RPMVSF_NODSAHEADER)
442 if (entry->info.type != RPM_BIN_TYPE) {
443 (void) snprintf(buf, sizeof(buf), _("hdr DSA: BAD, not binary\n"));
446 *info = entry->info; /* structure assignment */
447 siglen = info->count;
456 /* Return determined RPMRC_OK/RPMRC_FAIL conditions. */
457 if (rc != RPMRC_NOTFOUND) {
458 buf[sizeof(buf)-1] = '\0';
459 if (msg) *msg = xstrdup(buf);
464 /* If no header-only digest/signature, then do simple sanity check. */
465 if (info->tag == 0) {
467 xx = headerVerifyInfo(ril-1, dl, pe+1, &entry->info, 0);
469 (void) snprintf(buf, sizeof(buf),
470 _("tag[%d]: BAD, tag %d type %d offset %d count %d\n"),
471 xx+1, entry->info.tag, entry->info.type,
472 entry->info.offset, entry->info.count);
475 (void) snprintf(buf, sizeof(buf), "Header sanity check: OK\n");
478 buf[sizeof(buf)-1] = '\0';
479 if (msg) *msg = xstrdup(buf);
484 /* Verify header-only digest/signature. */
487 goto verifyinfo_exit;
490 sig = memcpy(xmalloc(siglen), dataStart + info->offset, siglen);
491 (void) rpmtsSetSig(ts, info->tag, info->type, sig, (size_t) info->count);
494 case RPMTAG_RSAHEADER:
495 /* Parse the parameters from the OpenPGP packets that will be needed. */
496 xx = pgpPrtPkts(sig, info->count, dig, (_print_pkts & rpmIsDebug()));
497 if (dig->signature.version != 3 && dig->signature.version != 4) {
499 _("skipping header with unverifiable V%u signature\n"),
500 dig->signature.version);
506 ildl[0] = htonl(ril);
507 ildl[1] = (regionEnd - dataStart);
508 ildl[1] = htonl(ildl[1]);
510 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
511 dig->hdrmd5ctx = rpmDigestInit(dig->signature.hash_algo, RPMDIGEST_NONE);
513 b = (unsigned char *) header_magic;
514 nb = sizeof(header_magic);
515 (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb);
518 b = (unsigned char *) ildl;
520 (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb);
523 b = (unsigned char *) pe;
524 nb = (htonl(ildl[0]) * sizeof(*pe));
525 (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb);
528 b = (unsigned char *) dataStart;
530 (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb);
532 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), dig->nbytes);
535 case RPMTAG_DSAHEADER:
536 /* Parse the parameters from the OpenPGP packets that will be needed. */
537 xx = pgpPrtPkts(sig, info->count, dig, (_print_pkts & rpmIsDebug()));
538 if (dig->signature.version != 3 && dig->signature.version != 4) {
540 _("skipping header with unverifiable V%u signature\n"),
541 dig->signature.version);
546 case RPMTAG_SHA1HEADER:
547 ildl[0] = htonl(ril);
548 ildl[1] = (regionEnd - dataStart);
549 ildl[1] = htonl(ildl[1]);
551 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
552 dig->hdrsha1ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
554 b = (unsigned char *) header_magic;
555 nb = sizeof(header_magic);
556 (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
559 b = (unsigned char *) ildl;
561 (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
564 b = (unsigned char *) pe;
565 nb = (htonl(ildl[0]) * sizeof(*pe));
566 (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
569 b = (unsigned char *) dataStart;
571 (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
573 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), dig->nbytes);
582 rc = rpmVerifySignature(ts, buf);
584 buf[sizeof(buf)-1] = '\0';
585 if (msg) *msg = xstrdup(buf);
587 /* XXX headerCheck can recurse, free info only at top level. */
590 if (info->tag == RPMTAG_SHA1HEADER)
596 rpmRC rpmReadHeader(rpmts ts, FD_t fd, Header *hdrp, char ** msg)
606 rpmRC rc = RPMRC_FAIL; /* assume failure */
616 memset(block, 0, sizeof(block));
617 if ((xx = timedRead(fd, (char *)block, sizeof(block))) != sizeof(block)) {
618 (void) snprintf(buf, sizeof(buf),
619 _("hdr size(%d): BAD, read returned %d\n"), (int)sizeof(block), xx);
622 if (memcmp(block, header_magic, sizeof(header_magic))) {
623 (void) snprintf(buf, sizeof(buf), _("hdr magic: BAD\n"));
626 il = ntohl(block[2]);
627 if (hdrchkTags(il)) {
628 (void) snprintf(buf, sizeof(buf),
629 _("hdr tags: BAD, no. of tags(%d) out of range\n"), il);
633 dl = ntohl(block[3]);
634 if (hdrchkData(dl)) {
635 (void) snprintf(buf, sizeof(buf),
636 _("hdr data: BAD, no. of bytes(%d) out of range\n"), dl);
640 nb = (il * sizeof(struct entryInfo_s)) + dl;
641 uc = sizeof(il) + sizeof(dl) + nb;
645 if ((xx = timedRead(fd, (char *)&ei[2], nb)) != nb) {
646 (void) snprintf(buf, sizeof(buf),
647 _("hdr blob(%zd): BAD, read returned %d\n"), nb, xx);
651 /* Sanity check header tags */
652 rc = headerCheck(ts, ei, uc, msg);
656 /* OK, blob looks sane, load the header. */
659 (void) snprintf(buf, sizeof(buf), _("hdr load: BAD\n"));
662 h->flags |= HEADERFLAG_ALLOCATED;
663 ei = NULL; /* XXX will be freed with header */
666 if (hdrp && h && rc == RPMRC_OK)
667 *hdrp = headerLink(h);
671 if (msg != NULL && *msg == NULL && buf[0] != '\0') {
672 buf[sizeof(buf)-1] = '\0';
679 rpmRC rpmReadPackageFile(rpmts ts, FD_t fd, const char * fn, Header * hdrp)
695 rpmRC rc = RPMRC_FAIL; /* assume failure */
698 if (hdrp) *hdrp = NULL;
702 if ((rc = rpmLeadRead(fd, l)) == RPMRC_OK) {
703 rc = rpmLeadCheck(l, fn);
710 /* Read the signature header. */
712 rc = rpmReadSignature(fd, &sigh, RPMSIGTYPE_HEADERSIG, &msg);
715 rpmlog(RPMLOG_ERR, _("%s: rpmReadSignature failed: %s"), fn,
716 (msg && *msg ? msg : "\n"));
722 rpmlog(RPMLOG_ERR, _("%s: No signature available\n"), fn);
730 #define _chk(_mask) (sigtag == 0 && !(vsflags & (_mask)))
733 * Figger the most effective available signature.
734 * Prefer signatures over digests, then header-only over header+payload.
735 * DSA will be preferred over RSA if both exist because tested first.
736 * Note that NEEDPAYLOAD prevents header+payload signatures and digests.
740 vsflags = rpmtsVSFlags(ts);
741 if (_chk(RPMVSF_NODSAHEADER) && headerIsEntry(sigh, RPMSIGTAG_DSA)) {
742 sigtag = RPMSIGTAG_DSA;
744 if (_chk(RPMVSF_NORSAHEADER) && headerIsEntry(sigh, RPMSIGTAG_RSA)) {
745 sigtag = RPMSIGTAG_RSA;
747 if (_chk(RPMVSF_NODSA|RPMVSF_NEEDPAYLOAD) &&
748 headerIsEntry(sigh, RPMSIGTAG_GPG))
750 sigtag = RPMSIGTAG_GPG;
751 fdInitDigest(fd, PGPHASHALGO_SHA1, 0);
752 opx = RPMTS_OP_SIGNATURE;
754 if (_chk(RPMVSF_NORSA|RPMVSF_NEEDPAYLOAD) &&
755 headerIsEntry(sigh, RPMSIGTAG_PGP))
757 sigtag = RPMSIGTAG_PGP;
758 fdInitDigest(fd, PGPHASHALGO_MD5, 0);
759 opx = RPMTS_OP_SIGNATURE;
761 if (_chk(RPMVSF_NOSHA1HEADER) && headerIsEntry(sigh, RPMSIGTAG_SHA1)) {
762 sigtag = RPMSIGTAG_SHA1;
764 if (_chk(RPMVSF_NOMD5|RPMVSF_NEEDPAYLOAD) &&
765 headerIsEntry(sigh, RPMSIGTAG_MD5))
767 sigtag = RPMSIGTAG_MD5;
768 fdInitDigest(fd, PGPHASHALGO_MD5, 0);
769 opx = RPMTS_OP_DIGEST;
772 /* Read the metadata, computing digest(s) on the fly. */
776 /* XXX stats will include header i/o and setup overhead. */
777 /* XXX repackaged packages have appended tags, legacy dig/sig check fails */
779 (void) rpmswEnter(rpmtsOp(ts, opx), 0);
780 nb = -fd->stats->ops[FDSTAT_READ].bytes;
781 rc = rpmReadHeader(ts, fd, &h, &msg);
782 nb += fd->stats->ops[FDSTAT_READ].bytes;
784 (void) rpmswExit(rpmtsOp(ts, opx), nb);
786 if (rc != RPMRC_OK || h == NULL) {
787 rpmlog(RPMLOG_ERR, _("%s: headerRead failed: %s"), fn,
788 (msg && *msg ? msg : "\n"));
794 /* Any digests or signatures to check? */
807 /* Retrieve the tag parameters from the signature header. */
809 xx = headerGetEntry(sigh, sigtag, &sigtype, &sig, &siglen);
814 (void) rpmtsSetSig(ts, sigtag, sigtype, sig, siglen);
818 /* Parse the parameters from the OpenPGP packets that will be needed. */
819 xx = pgpPrtPkts(sig, siglen, dig, (_print_pkts & rpmIsDebug()));
820 if (dig->signature.version != 3 && dig->signature.version != 4) {
822 _("skipping package %s with unverifiable V%u signature\n"),
823 fn, dig->signature.version);
831 if (!headerGetEntry(h, RPMTAG_HEADERIMMUTABLE, &uht, &uh, &uhc))
833 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
834 dig->hdrmd5ctx = rpmDigestInit(dig->signature.hash_algo, RPMDIGEST_NONE);
835 (void) rpmDigestUpdate(dig->hdrmd5ctx, header_magic, sizeof(header_magic));
836 dig->nbytes += sizeof(header_magic);
837 (void) rpmDigestUpdate(dig->hdrmd5ctx, uh, uhc);
839 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), dig->nbytes);
840 rpmtsOp(ts, RPMTS_OP_DIGEST)->count--; /* XXX one too many */
841 uh = headerFreeData(uh, uht);
844 /* Parse the parameters from the OpenPGP packets that will be needed. */
845 xx = pgpPrtPkts(sig, siglen, dig, (_print_pkts & rpmIsDebug()));
846 if (dig->signature.version != 3 && dig->signature.version != 4) {
848 _("skipping package %s with unverifiable V%u signature\n"),
849 fn, dig->signature.version);
858 if (!headerGetEntry(h, RPMTAG_HEADERIMMUTABLE, &uht, &uh, &uhc))
860 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
861 dig->hdrsha1ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
862 (void) rpmDigestUpdate(dig->hdrsha1ctx, header_magic, sizeof(header_magic));
863 dig->nbytes += sizeof(header_magic);
864 (void) rpmDigestUpdate(dig->hdrsha1ctx, uh, uhc);
866 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), dig->nbytes);
867 if (sigtag == RPMSIGTAG_SHA1)
868 rpmtsOp(ts, RPMTS_OP_DIGEST)->count--; /* XXX one too many */
869 uh = headerFreeData(uh, uht);
872 case RPMSIGTAG_PGP5: /* XXX legacy */
874 /* Parse the parameters from the OpenPGP packets that will be needed. */
875 xx = pgpPrtPkts(sig, siglen, dig, (_print_pkts & rpmIsDebug()));
877 if (dig->signature.version != 3 && dig->signature.version != 4) {
879 _("skipping package %s with unverifiable V%u signature\n"),
880 fn, dig->signature.version);
885 /* Legacy signatures need the compressed payload in the digest too. */
886 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
887 while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), fd)) > 0)
888 dig->nbytes += count;
889 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), dig->nbytes);
890 rpmtsOp(ts, RPMTS_OP_DIGEST)->count--; /* XXX one too many */
891 dig->nbytes += nb; /* XXX include size of header blob. */
893 rpmlog(RPMLOG_ERR, _("%s: Fread failed: %s\n"),
899 fdStealDigest(fd, dig);
902 case RPMSIGTAG_LEMD5_1:
903 case RPMSIGTAG_LEMD5_2:
904 case RPMSIGTAG_BADSHA1_1:
905 case RPMSIGTAG_BADSHA1_2:
907 case RPMSIGTAG_PAYLOADSIZE:
911 /** @todo Implement disable/enable/warn/error/anal policy. */
914 rc = rpmVerifySignature(ts, buf);
916 case RPMRC_OK: /* Signature is OK. */
917 rpmlog(RPMLOG_DEBUG, "%s: %s", fn, buf);
919 case RPMRC_NOTTRUSTED: /* Signature is OK, but key is not trusted. */
920 case RPMRC_NOKEY: /* Public key is unavailable. */
921 /* XXX Print NOKEY/NOTTRUSTED warning only once. */
922 { int lvl = (rpmtsStashKeyid(ts) ? RPMLOG_DEBUG : RPMLOG_WARNING);
923 rpmlog(lvl, "%s: %s", fn, buf);
925 case RPMRC_NOTFOUND: /* Signature is unknown type. */
926 rpmlog(RPMLOG_WARNING, "%s: %s", fn, buf);
929 case RPMRC_FAIL: /* Signature does not verify. */
930 rpmlog(RPMLOG_ERR, "%s: %s", fn, buf);
935 if (rc != RPMRC_FAIL && h != NULL && hdrp != NULL) {
937 * Convert legacy headers on the fly. Not having "new" style compressed
938 * filenames is close enough estimate for legacy indication...
940 if (!headerIsEntry(h, RPMTAG_DIRNAMES)) {
944 /* Append (and remap) signature tags to the metadata. */
945 headerMergeLegacySigs(h, sigh);
947 /* Bump reference count for return. */
948 *hdrp = headerLink(h);
952 sigh = rpmFreeSignature(sigh);
957 * Check for supported payload format in header.
958 * @param h header to check
959 * @return RPMRC_OK if supported, RPMRC_FAIL otherwise
961 rpmRC headerCheckPayloadFormat(Header h) {
962 rpmRC rc = RPMRC_FAIL;
964 const char *payloadfmt = NULL;
966 xx = headerGetEntry(h, RPMTAG_PAYLOADFORMAT, NULL,
967 (rpm_data_t *)&payloadfmt, NULL);
969 * XXX Ugh, rpm 3.x packages don't have payload format tag. Instead
970 * of blinly allowing, should check somehow (HDRID existence or... ?)
975 if (payloadfmt && strncmp(payloadfmt, "cpio", strlen("cpio")) == 0) {
978 char *nevra = headerGetNEVRA(h, NULL);
979 if (payloadfmt && strncmp(payloadfmt, "drpm", strlen("drpm")) == 0) {
981 _("%s is a Delta RPM and cannot be directly installed\n"),
985 _("Unsupported payload (%s) in package %s\n"),
986 payloadfmt ? payloadfmt : "none", nevra);
988 nevra = _free(nevra);