00001
00005 #include "system.h"
00006
00007 #include <netinet/in.h>
00008
00009 #include <rpmio_internal.h>
00010 #include <rpmlib.h>
00011
00012 #include "rpmts.h"
00013
00014 #include "misc.h"
00015 #include "legacy.h"
00016 #include "rpmlead.h"
00017
00018 #include "header_internal.h"
00019 #include "signature.h"
00020 #include "debug.h"
00021
00022 #define alloca_strdup(_s) strcpy(alloca(strlen(_s)+1), (_s))
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 static int _print_pkts = 0;
00033
00034
00035 static unsigned int nkeyids_max = 256;
00036
00037 static unsigned int nkeyids = 0;
00038
00039 static unsigned int nextkeyid = 0;
00040
00041 static unsigned int * keyids;
00042
00043
00044 static unsigned char header_magic[8] = {
00045 0x8e, 0xad, 0xe8, 0x01, 0x00, 0x00, 0x00, 0x00
00046 };
00047
00051
00052 static int typeAlign[16] = {
00053 1,
00054 1,
00055 1,
00056 2,
00057 4,
00058 8,
00059 1,
00060 1,
00061 1,
00062 1,
00063 0,
00064 0,
00065 0,
00066 0,
00067 0,
00068 0
00069 };
00070
00075 #define hdrchkTags(_ntags) ((_ntags) & 0xffff0000)
00076
00080 #define hdrchkType(_type) ((_type) < RPM_MIN_TYPE || (_type) > RPM_MAX_TYPE)
00081
00086 #define hdrchkData(_nbytes) ((_nbytes) & 0xff000000)
00087
00091 #define hdrchkAlign(_type, _off) ((_off) & (typeAlign[_type]-1))
00092
00096 #define hdrchkRange(_dl, _off) ((_off) < 0 || (_off) > (_dl))
00097
00098 void headerMergeLegacySigs(Header h, const Header sigh)
00099 {
00100 HFD_t hfd = (HFD_t) headerFreeData;
00101 HAE_t hae = (HAE_t) headerAddEntry;
00102 HeaderIterator hi;
00103 int_32 tag, type, count;
00104 const void * ptr;
00105 int xx;
00106
00107 for (hi = headerInitIterator(sigh);
00108 headerNextIterator(hi, &tag, &type, &ptr, &count);
00109 ptr = hfd(ptr, type))
00110 {
00111 switch (tag) {
00112
00113 case RPMSIGTAG_SIZE:
00114 tag = RPMTAG_SIGSIZE;
00115 break;
00116 case RPMSIGTAG_LEMD5_1:
00117 tag = RPMTAG_SIGLEMD5_1;
00118 break;
00119 case RPMSIGTAG_PGP:
00120 tag = RPMTAG_SIGPGP;
00121 break;
00122 case RPMSIGTAG_LEMD5_2:
00123 tag = RPMTAG_SIGLEMD5_2;
00124 break;
00125 case RPMSIGTAG_MD5:
00126 tag = RPMTAG_SIGMD5;
00127 break;
00128 case RPMSIGTAG_GPG:
00129 tag = RPMTAG_SIGGPG;
00130 break;
00131 case RPMSIGTAG_PGP5:
00132 tag = RPMTAG_SIGPGP5;
00133 break;
00134 case RPMSIGTAG_PAYLOADSIZE:
00135 tag = RPMTAG_ARCHIVESIZE;
00136 break;
00137 case RPMSIGTAG_SHA1:
00138 case RPMSIGTAG_DSA:
00139 case RPMSIGTAG_RSA:
00140 default:
00141 if (!(tag >= HEADER_SIGBASE && tag < HEADER_TAGBASE))
00142 continue;
00143 break;
00144 }
00145 if (ptr == NULL) continue;
00146 if (!headerIsEntry(h, tag)) {
00147 if (hdrchkType(type))
00148 continue;
00149 if (count < 0 || hdrchkData(count))
00150 continue;
00151 switch(type) {
00152 case RPM_NULL_TYPE:
00153 continue;
00154 break;
00155 case RPM_CHAR_TYPE:
00156 case RPM_INT8_TYPE:
00157 case RPM_INT16_TYPE:
00158 case RPM_INT32_TYPE:
00159 if (count != 1)
00160 continue;
00161 break;
00162 case RPM_STRING_TYPE:
00163 case RPM_BIN_TYPE:
00164 if (count >= 16*1024)
00165 continue;
00166 break;
00167 case RPM_STRING_ARRAY_TYPE:
00168 case RPM_I18NSTRING_TYPE:
00169 continue;
00170 break;
00171 }
00172 xx = hae(h, tag, type, ptr, count);
00173 }
00174 }
00175 hi = headerFreeIterator(hi);
00176 }
00177
00178 Header headerRegenSigHeader(const Header h, int noArchiveSize)
00179 {
00180 HFD_t hfd = (HFD_t) headerFreeData;
00181 Header sigh = rpmNewSignature();
00182 HeaderIterator hi;
00183 int_32 tag, stag, type, count;
00184 const void * ptr;
00185 int xx;
00186
00187 for (hi = headerInitIterator(h);
00188 headerNextIterator(hi, &tag, &type, &ptr, &count);
00189 ptr = hfd(ptr, type))
00190 {
00191 switch (tag) {
00192
00193 case RPMTAG_SIGSIZE:
00194 stag = RPMSIGTAG_SIZE;
00195 break;
00196 case RPMTAG_SIGLEMD5_1:
00197 stag = RPMSIGTAG_LEMD5_1;
00198 break;
00199 case RPMTAG_SIGPGP:
00200 stag = RPMSIGTAG_PGP;
00201 break;
00202 case RPMTAG_SIGLEMD5_2:
00203 stag = RPMSIGTAG_LEMD5_2;
00204 break;
00205 case RPMTAG_SIGMD5:
00206 stag = RPMSIGTAG_MD5;
00207 break;
00208 case RPMTAG_SIGGPG:
00209 stag = RPMSIGTAG_GPG;
00210 break;
00211 case RPMTAG_SIGPGP5:
00212 stag = RPMSIGTAG_PGP5;
00213 break;
00214 case RPMTAG_ARCHIVESIZE:
00215
00216 if (noArchiveSize)
00217 continue;
00218 stag = RPMSIGTAG_PAYLOADSIZE;
00219 break;
00220 case RPMTAG_SHA1HEADER:
00221 case RPMTAG_DSAHEADER:
00222 case RPMTAG_RSAHEADER:
00223 default:
00224 if (!(tag >= HEADER_SIGBASE && tag < HEADER_TAGBASE))
00225 continue;
00226 stag = tag;
00227 break;
00228 }
00229 if (ptr == NULL) continue;
00230 if (!headerIsEntry(sigh, stag))
00231 xx = headerAddEntry(sigh, stag, type, ptr, count);
00232 }
00233 hi = headerFreeIterator(hi);
00234 return sigh;
00235 }
00236
00242 static int rpmtsStashKeyid(rpmts ts)
00243
00244
00245 {
00246 const void * sig = rpmtsSig(ts);
00247 pgpDig dig = rpmtsDig(ts);
00248 pgpDigParams sigp = rpmtsSignature(ts);
00249 unsigned int keyid;
00250 int i;
00251
00252 if (sig == NULL || dig == NULL || sigp == NULL)
00253 return 0;
00254
00255 keyid = pgpGrab(sigp->signid+4, 4);
00256 if (keyid == 0)
00257 return 0;
00258
00259 if (keyids != NULL)
00260 for (i = 0; i < nkeyids; i++) {
00261
00262 if (keyid == keyids[i])
00263 return 1;
00264
00265 }
00266
00267 if (nkeyids < nkeyids_max) {
00268 nkeyids++;
00269 keyids = xrealloc(keyids, nkeyids * sizeof(*keyids));
00270 }
00271
00272 if (keyids)
00273 keyids[nextkeyid] = keyid;
00274
00275 nextkeyid++;
00276 nextkeyid %= nkeyids_max;
00277
00278 return 0;
00279 }
00280
00281 int headerVerifyInfo(int il, int dl, const void * pev, void * iv, int negate)
00282 {
00283
00284 entryInfo pe = (entryInfo) pev;
00285
00286 entryInfo info = iv;
00287 int i;
00288
00289
00290 for (i = 0; i < il; i++) {
00291 info->tag = ntohl(pe[i].tag);
00292 info->type = ntohl(pe[i].type);
00293 info->offset = ntohl(pe[i].offset);
00294 if (negate)
00295 info->offset = -info->offset;
00296 info->count = ntohl(pe[i].count);
00297
00298 if (hdrchkType(info->type))
00299 return i;
00300 if (hdrchkAlign(info->type, info->offset))
00301 return i;
00302 if (!negate && hdrchkRange(dl, info->offset))
00303 return i;
00304 if (hdrchkData(info->count))
00305 return i;
00306
00307 }
00308
00309 return -1;
00310 }
00311
00325 rpmRC headerCheck(rpmts ts, const void * uh, size_t uc, const char ** msg)
00326 {
00327 pgpDig dig;
00328 unsigned char buf[8*BUFSIZ];
00329 int_32 * ei = (int_32 *) uh;
00330
00331 int_32 il = ntohl(ei[0]);
00332 int_32 dl = ntohl(ei[1]);
00333
00334 entryInfo pe = (entryInfo) &ei[2];
00335
00336
00337 int_32 ildl[2];
00338 int_32 pvlen = sizeof(ildl) + (il * sizeof(*pe)) + dl;
00339 unsigned char * dataStart = (unsigned char *) (pe + il);
00340 indexEntry entry = memset(alloca(sizeof(*entry)), 0, sizeof(*entry));
00341 entryInfo info = memset(alloca(sizeof(*info)), 0, sizeof(*info));
00342 const void * sig = NULL;
00343 const char * b;
00344 rpmVSFlags vsflags = rpmtsVSFlags(ts);
00345 int siglen = 0;
00346 int blen;
00347 size_t nb;
00348 int_32 ril = 0;
00349 unsigned char * regionEnd = NULL;
00350 rpmRC rc = RPMRC_FAIL;
00351 int xx;
00352 int i;
00353 static int hclvl;
00354
00355 hclvl++;
00356
00357 buf[0] = '\0';
00358
00359
00360
00361 if (uc > 0 && pvlen != uc) {
00362 (void) snprintf(buf, sizeof(buf),
00363 _("blob size(%d): BAD, 8 + 16 * il(%d) + dl(%d)\n"),
00364 (int)uc, (int)il, (int)dl);
00365 goto exit;
00366 }
00367
00368
00369 xx = headerVerifyInfo(1, dl, pe, &entry->info, 0);
00370 if (xx != -1) {
00371 (void) snprintf(buf, sizeof(buf),
00372 _("tag[%d]: BAD, tag %d type %d offset %d count %d\n"),
00373 0, entry->info.tag, entry->info.type,
00374 entry->info.offset, entry->info.count);
00375 goto exit;
00376 }
00377
00378
00379
00380 if (!(entry->info.tag == RPMTAG_HEADERIMMUTABLE
00381 && entry->info.type == RPM_BIN_TYPE
00382 && entry->info.count == REGION_TAG_COUNT))
00383 {
00384 rc = RPMRC_NOTFOUND;
00385 goto exit;
00386 }
00387
00388
00389
00390 if (entry->info.offset >= dl) {
00391 (void) snprintf(buf, sizeof(buf),
00392 _("region offset: BAD, tag %d type %d offset %d count %d\n"),
00393 entry->info.tag, entry->info.type,
00394 entry->info.offset, entry->info.count);
00395 goto exit;
00396 }
00397
00398
00399 regionEnd = dataStart + entry->info.offset;
00400
00401
00402 (void) memcpy(info, regionEnd, REGION_TAG_COUNT);
00403
00404 regionEnd += REGION_TAG_COUNT;
00405
00406 xx = headerVerifyInfo(1, dl, info, &entry->info, 1);
00407 if (xx != -1 ||
00408 !(entry->info.tag == RPMTAG_HEADERIMMUTABLE
00409 && entry->info.type == RPM_BIN_TYPE
00410 && entry->info.count == REGION_TAG_COUNT))
00411 {
00412 (void) snprintf(buf, sizeof(buf),
00413 _("region trailer: BAD, tag %d type %d offset %d count %d\n"),
00414 entry->info.tag, entry->info.type,
00415 entry->info.offset, entry->info.count);
00416 goto exit;
00417 }
00418
00419
00420 memset(info, 0, sizeof(*info));
00421
00422
00423
00424 ril = entry->info.offset/sizeof(*pe);
00425 if ((entry->info.offset % sizeof(*pe)) || ril > il) {
00426 (void) snprintf(buf, sizeof(buf),
00427 _("region size: BAD, ril(%d) > il(%d)\n"), ril, il);
00428 goto exit;
00429 }
00430
00431
00432 for (i = ril; i < il; i++) {
00433 xx = headerVerifyInfo(1, dl, pe+i, &entry->info, 0);
00434 if (xx != -1) {
00435 (void) snprintf(buf, sizeof(buf),
00436 _("tag[%d]: BAD, tag %d type %d offset %d count %d\n"),
00437 i, entry->info.tag, entry->info.type,
00438 entry->info.offset, entry->info.count);
00439 goto exit;
00440 }
00441
00442 switch (entry->info.tag) {
00443 case RPMTAG_SHA1HEADER:
00444 if (vsflags & RPMVSF_NOSHA1HEADER)
00445 break;
00446 blen = 0;
00447
00448 for (b = dataStart + entry->info.offset; *b != '\0'; b++) {
00449 if (strchr("0123456789abcdefABCDEF", *b) == NULL)
00450 break;
00451 blen++;
00452 }
00453 if (entry->info.type != RPM_STRING_TYPE || *b != '\0' || blen != 40)
00454 {
00455 (void) snprintf(buf, sizeof(buf), _("hdr SHA1: BAD, not hex\n"));
00456 goto exit;
00457 }
00458
00459 if (info->tag == 0) {
00460
00461 *info = entry->info;
00462
00463 siglen = blen + 1;
00464 }
00465 break;
00466 case RPMTAG_RSAHEADER:
00467 if (vsflags & RPMVSF_NORSAHEADER)
00468 break;
00469 if (entry->info.type != RPM_BIN_TYPE) {
00470 (void) snprintf(buf, sizeof(buf), _("hdr RSA: BAD, not binary\n"));
00471 goto exit;
00472 }
00473
00474 *info = entry->info;
00475
00476 siglen = info->count;
00477 break;
00478 case RPMTAG_DSAHEADER:
00479 if (vsflags & RPMVSF_NODSAHEADER)
00480 break;
00481 if (entry->info.type != RPM_BIN_TYPE) {
00482 (void) snprintf(buf, sizeof(buf), _("hdr DSA: BAD, not binary\n"));
00483 goto exit;
00484 }
00485
00486 *info = entry->info;
00487
00488 siglen = info->count;
00489 break;
00490 default:
00491 break;
00492 }
00493 }
00494 rc = RPMRC_NOTFOUND;
00495
00496 exit:
00497
00498 if (rc != RPMRC_NOTFOUND) {
00499
00500 buf[sizeof(buf)-1] = '\0';
00501 if (msg) *msg = xstrdup(buf);
00502
00503 hclvl--;
00504 return rc;
00505 }
00506
00507
00508 if (info->tag == 0) {
00509 verifyinfo_exit:
00510 xx = headerVerifyInfo(ril-1, dl, pe+1, &entry->info, 0);
00511 if (xx != -1) {
00512 (void) snprintf(buf, sizeof(buf),
00513 _("tag[%d]: BAD, tag %d type %d offset %d count %d\n"),
00514 xx+1, entry->info.tag, entry->info.type,
00515 entry->info.offset, entry->info.count);
00516 rc = RPMRC_FAIL;
00517 } else {
00518 (void) snprintf(buf, sizeof(buf), "Header sanity check: OK\n");
00519 rc = RPMRC_OK;
00520 }
00521
00522 buf[sizeof(buf)-1] = '\0';
00523 if (msg) *msg = xstrdup(buf);
00524
00525 hclvl--;
00526 return rc;
00527 }
00528
00529
00530 dig = rpmtsDig(ts);
00531 if (dig == NULL)
00532 goto verifyinfo_exit;
00533 dig->nbytes = 0;
00534
00535
00536 sig = memcpy(xmalloc(siglen), dataStart + info->offset, siglen);
00537
00538 (void) rpmtsSetSig(ts, info->tag, info->type, sig, info->count);
00539
00540 switch (info->tag) {
00541 case RPMTAG_RSAHEADER:
00542
00543 xx = pgpPrtPkts(sig, info->count, dig, (_print_pkts & rpmIsDebug()));
00544 if (dig->signature.version != 3 && dig->signature.version != 4) {
00545 rpmMessage(RPMMESS_WARNING,
00546 _("only V3 and V4 signatures can be verified, skipping V%u signature\n"),
00547 dig->signature.version);
00548 rpmtsCleanDig(ts);
00549 goto verifyinfo_exit;
00550 }
00551
00552 ildl[0] = htonl(ril);
00553 ildl[1] = (regionEnd - dataStart);
00554 ildl[1] = htonl(ildl[1]);
00555
00556 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
00557 dig->hdrmd5ctx = rpmDigestInit(dig->signature.hash_algo, RPMDIGEST_NONE);
00558
00559 b = (unsigned char *) header_magic;
00560 nb = sizeof(header_magic);
00561 (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb);
00562 dig->nbytes += nb;
00563
00564 b = (unsigned char *) ildl;
00565 nb = sizeof(ildl);
00566 (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb);
00567 dig->nbytes += nb;
00568
00569 b = (unsigned char *) pe;
00570 nb = (htonl(ildl[0]) * sizeof(*pe));
00571 (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb);
00572 dig->nbytes += nb;
00573
00574 b = (unsigned char *) dataStart;
00575 nb = htonl(ildl[1]);
00576 (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb);
00577 dig->nbytes += nb;
00578 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), dig->nbytes);
00579
00580 break;
00581 case RPMTAG_DSAHEADER:
00582
00583 xx = pgpPrtPkts(sig, info->count, dig, (_print_pkts & rpmIsDebug()));
00584 if (dig->signature.version != 3 && dig->signature.version != 4) {
00585 rpmMessage(RPMMESS_WARNING,
00586 _("only V3 and V4 signatures can be verified, skipping V%u signature\n"),
00587 dig->signature.version);
00588 rpmtsCleanDig(ts);
00589 goto verifyinfo_exit;
00590 }
00591
00592 case RPMTAG_SHA1HEADER:
00593
00594 ildl[0] = htonl(ril);
00595 ildl[1] = (regionEnd - dataStart);
00596 ildl[1] = htonl(ildl[1]);
00597
00598
00599 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
00600 dig->hdrsha1ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
00601
00602 b = (unsigned char *) header_magic;
00603 nb = sizeof(header_magic);
00604 (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
00605 dig->nbytes += nb;
00606
00607 b = (unsigned char *) ildl;
00608 nb = sizeof(ildl);
00609 (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
00610 dig->nbytes += nb;
00611
00612 b = (unsigned char *) pe;
00613 nb = (htonl(ildl[0]) * sizeof(*pe));
00614 (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
00615 dig->nbytes += nb;
00616
00617 b = (unsigned char *) dataStart;
00618 nb = htonl(ildl[1]);
00619 (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
00620 dig->nbytes += nb;
00621 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), dig->nbytes);
00622
00623 break;
00624 default:
00625 sig = _free(sig);
00626 break;
00627 }
00628
00629
00630 buf[0] = '\0';
00631
00632 rc = rpmVerifySignature(ts, buf);
00633
00634
00635 buf[sizeof(buf)-1] = '\0';
00636 if (msg) *msg = xstrdup(buf);
00637
00638
00639
00640 if (hclvl == 1)
00641 rpmtsCleanDig(ts);
00642 if (info->tag == RPMTAG_SHA1HEADER)
00643 sig = _free(sig);
00644 hclvl--;
00645 return rc;
00646 }
00647
00648 rpmRC rpmReadHeader(rpmts ts, FD_t fd, Header *hdrp, const char ** msg)
00649 {
00650 char buf[BUFSIZ];
00651 int_32 block[4];
00652 int_32 il;
00653 int_32 dl;
00654 int_32 * ei = NULL;
00655 size_t uc;
00656 int_32 nb;
00657 Header h = NULL;
00658 rpmRC rc = RPMRC_FAIL;
00659 int xx;
00660
00661
00662 buf[0] = '\0';
00663
00664 if (hdrp)
00665 *hdrp = NULL;
00666 if (msg)
00667 *msg = NULL;
00668
00669
00670 memset(block, 0, sizeof(block));
00671 if ((xx = timedRead(fd, (char *)block, sizeof(block))) != sizeof(block)) {
00672 (void) snprintf(buf, sizeof(buf),
00673 _("hdr size(%d): BAD, read returned %d\n"), (int)sizeof(block), xx);
00674 goto exit;
00675 }
00676 if (memcmp(block, header_magic, sizeof(header_magic))) {
00677 (void) snprintf(buf, sizeof(buf), _("hdr magic: BAD\n"));
00678 goto exit;
00679 }
00680
00681 il = ntohl(block[2]);
00682
00683 if (hdrchkTags(il)) {
00684 (void) snprintf(buf, sizeof(buf),
00685 _("hdr tags: BAD, no. of tags(%d) out of range\n"), il);
00686
00687 goto exit;
00688 }
00689
00690 dl = ntohl(block[3]);
00691
00692 if (hdrchkData(dl)) {
00693 (void) snprintf(buf, sizeof(buf),
00694 _("hdr data: BAD, no. of bytes(%d) out of range\n"), dl);
00695 goto exit;
00696 }
00697
00698
00699 nb = (il * sizeof(struct entryInfo_s)) + dl;
00700
00701 uc = sizeof(il) + sizeof(dl) + nb;
00702 ei = xmalloc(uc);
00703
00704 ei[0] = block[2];
00705 ei[1] = block[3];
00706 if ((xx = timedRead(fd, (char *)&ei[2], nb)) != nb) {
00707 (void) snprintf(buf, sizeof(buf),
00708 _("hdr blob(%d): BAD, read returned %d\n"), nb, xx);
00709 goto exit;
00710 }
00711
00712
00713
00714 rc = headerCheck(ts, ei, uc, msg);
00715 if (rc != RPMRC_OK)
00716 goto exit;
00717
00718
00719 h = headerLoad(ei);
00720 if (h == NULL) {
00721 (void) snprintf(buf, sizeof(buf), _("hdr load: BAD\n"));
00722 goto exit;
00723 }
00724 h->flags |= HEADERFLAG_ALLOCATED;
00725 ei = NULL;
00726
00727 exit:
00728
00729 if (hdrp && h && rc == RPMRC_OK)
00730 *hdrp = headerLink(h);
00731
00732 ei = _free(ei);
00733 h = headerFree(h);
00734
00735
00736 if (msg != NULL && *msg == NULL && buf[0] != '\0') {
00737 buf[sizeof(buf)-1] = '\0';
00738 *msg = xstrdup(buf);
00739 }
00740
00741
00742 return rc;
00743 }
00744
00745
00746 rpmRC rpmReadPackageFile(rpmts ts, FD_t fd, const char * fn, Header * hdrp)
00747 {
00748 pgpDig dig;
00749 byte buf[8*BUFSIZ];
00750 ssize_t count;
00751 struct rpmlead * l = alloca(sizeof(*l));
00752 Header sigh = NULL;
00753 int_32 sigtag;
00754 int_32 sigtype;
00755 const void * sig;
00756 int_32 siglen;
00757 rpmtsOpX opx;
00758 size_t nb;
00759 Header h = NULL;
00760 const char * msg;
00761 rpmVSFlags vsflags;
00762 rpmRC rc = RPMRC_FAIL;
00763 int xx;
00764 int i;
00765
00766 if (hdrp) *hdrp = NULL;
00767
00768 #ifdef DYING
00769 { struct stat st;
00770
00771 memset(&st, 0, sizeof(st));
00772
00773 (void) fstat(Fileno(fd), &st);
00774
00775 if (S_ISREG(st.st_mode) && st.st_size < sizeof(*l)) {
00776 rc = RPMRC_NOTFOUND;
00777 goto exit;
00778 }
00779 }
00780 #endif
00781
00782 memset(l, 0, sizeof(*l));
00783 rc = readLead(fd, l);
00784 if (rc != RPMRC_OK)
00785 goto exit;
00786
00787 switch (l->major) {
00788 case 1:
00789 rpmError(RPMERR_NEWPACKAGE,
00790 _("packaging version 1 is not supported by this version of RPM\n"));
00791 rc = RPMRC_NOTFOUND;
00792 goto exit;
00793 break;
00794 case 2:
00795 case 3:
00796 case 4:
00797 break;
00798 default:
00799 rpmError(RPMERR_NEWPACKAGE, _("only packaging with major numbers <= 4 "
00800 "is supported by this version of RPM\n"));
00801 rc = RPMRC_NOTFOUND;
00802 goto exit;
00803 break;
00804 }
00805
00806
00807 msg = NULL;
00808 rc = rpmReadSignature(fd, &sigh, l->signature_type, &msg);
00809 switch (rc) {
00810 default:
00811 rpmError(RPMERR_SIGGEN, _("%s: rpmReadSignature failed: %s"), fn,
00812 (msg && *msg ? msg : "\n"));
00813 msg = _free(msg);
00814 goto exit;
00815 break;
00816 case RPMRC_OK:
00817 if (sigh == NULL) {
00818 rpmError(RPMERR_SIGGEN, _("%s: No signature available\n"), fn);
00819 rc = RPMRC_FAIL;
00820 goto exit;
00821 }
00822 break;
00823 }
00824 msg = _free(msg);
00825
00826 #define _chk(_mask) (sigtag == 0 && !(vsflags & (_mask)))
00827
00828
00829
00830
00831
00832
00833
00834 sigtag = 0;
00835 opx = 0;
00836 vsflags = rpmtsVSFlags(ts);
00837 if (_chk(RPMVSF_NODSAHEADER) && headerIsEntry(sigh, RPMSIGTAG_DSA)) {
00838 sigtag = RPMSIGTAG_DSA;
00839 } else
00840 if (_chk(RPMVSF_NORSAHEADER) && headerIsEntry(sigh, RPMSIGTAG_RSA)) {
00841 sigtag = RPMSIGTAG_RSA;
00842 } else
00843 if (_chk(RPMVSF_NODSA|RPMVSF_NEEDPAYLOAD) &&
00844 headerIsEntry(sigh, RPMSIGTAG_GPG))
00845 {
00846 sigtag = RPMSIGTAG_GPG;
00847 fdInitDigest(fd, PGPHASHALGO_SHA1, 0);
00848 opx = RPMTS_OP_SIGNATURE;
00849 } else
00850 if (_chk(RPMVSF_NORSA|RPMVSF_NEEDPAYLOAD) &&
00851 headerIsEntry(sigh, RPMSIGTAG_PGP))
00852 {
00853 sigtag = RPMSIGTAG_PGP;
00854 fdInitDigest(fd, PGPHASHALGO_MD5, 0);
00855 opx = RPMTS_OP_SIGNATURE;
00856 } else
00857 if (_chk(RPMVSF_NOSHA1HEADER) && headerIsEntry(sigh, RPMSIGTAG_SHA1)) {
00858 sigtag = RPMSIGTAG_SHA1;
00859 } else
00860 if (_chk(RPMVSF_NOMD5|RPMVSF_NEEDPAYLOAD) &&
00861 headerIsEntry(sigh, RPMSIGTAG_MD5))
00862 {
00863 sigtag = RPMSIGTAG_MD5;
00864 fdInitDigest(fd, PGPHASHALGO_MD5, 0);
00865 opx = RPMTS_OP_DIGEST;
00866 }
00867
00868
00869 h = NULL;
00870 msg = NULL;
00871
00872
00873
00874 if (opx > 0)
00875 (void) rpmswEnter(rpmtsOp(ts, opx), 0);
00876
00877 nb = -fd->stats->ops[FDSTAT_READ].bytes;
00878 rc = rpmReadHeader(ts, fd, &h, &msg);
00879 nb += fd->stats->ops[FDSTAT_READ].bytes;
00880
00881 if (opx > 0)
00882 (void) rpmswExit(rpmtsOp(ts, opx), nb);
00883
00884 if (rc != RPMRC_OK || h == NULL) {
00885 rpmError(RPMERR_FREAD, _("%s: headerRead failed: %s"), fn,
00886 (msg && *msg ? msg : "\n"));
00887 msg = _free(msg);
00888 goto exit;
00889 }
00890 msg = _free(msg);
00891
00892
00893 if (sigtag == 0) {
00894 rc = RPMRC_OK;
00895 goto exit;
00896 }
00897
00898 dig = rpmtsDig(ts);
00899 if (dig == NULL) {
00900 rc = RPMRC_FAIL;
00901 goto exit;
00902 }
00903 dig->nbytes = 0;
00904
00905
00906 sig = NULL;
00907 xx = headerGetEntry(sigh, sigtag, &sigtype, (void **) &sig, &siglen);
00908 if (sig == NULL) {
00909 rc = RPMRC_FAIL;
00910 goto exit;
00911 }
00912 (void) rpmtsSetSig(ts, sigtag, sigtype, sig, siglen);
00913
00914 switch (sigtag) {
00915 case RPMSIGTAG_RSA:
00916
00917 xx = pgpPrtPkts(sig, siglen, dig, (_print_pkts & rpmIsDebug()));
00918 if (dig->signature.version != 3 && dig->signature.version != 4) {
00919 rpmMessage(RPMMESS_WARNING,
00920 _("only V3 and V4 signatures can be verified, skipping V%u signature\n"),
00921 dig->signature.version);
00922 rc = RPMRC_OK;
00923 goto exit;
00924 }
00925 { void * uh = NULL;
00926 int_32 uht;
00927 int_32 uhc;
00928
00929 if (!headerGetEntry(h, RPMTAG_HEADERIMMUTABLE, &uht, &uh, &uhc))
00930 break;
00931 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
00932 dig->hdrmd5ctx = rpmDigestInit(dig->signature.hash_algo, RPMDIGEST_NONE);
00933 (void) rpmDigestUpdate(dig->hdrmd5ctx, header_magic, sizeof(header_magic));
00934 dig->nbytes += sizeof(header_magic);
00935 (void) rpmDigestUpdate(dig->hdrmd5ctx, uh, uhc);
00936 dig->nbytes += uhc;
00937 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), dig->nbytes);
00938 rpmtsOp(ts, RPMTS_OP_DIGEST)->count--;
00939 uh = headerFreeData(uh, uht);
00940 } break;
00941 case RPMSIGTAG_DSA:
00942
00943 xx = pgpPrtPkts(sig, siglen, dig, (_print_pkts & rpmIsDebug()));
00944 if (dig->signature.version != 3 && dig->signature.version != 4) {
00945 rpmMessage(RPMMESS_WARNING,
00946 _("only V3 and V4 signatures can be verified, skipping V%u signature\n"),
00947 dig->signature.version);
00948 rc = RPMRC_OK;
00949 goto exit;
00950 }
00951
00952 case RPMSIGTAG_SHA1:
00953 { void * uh = NULL;
00954 int_32 uht;
00955 int_32 uhc;
00956
00957 if (!headerGetEntry(h, RPMTAG_HEADERIMMUTABLE, &uht, &uh, &uhc))
00958 break;
00959 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
00960 dig->hdrsha1ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
00961 (void) rpmDigestUpdate(dig->hdrsha1ctx, header_magic, sizeof(header_magic));
00962 dig->nbytes += sizeof(header_magic);
00963 (void) rpmDigestUpdate(dig->hdrsha1ctx, uh, uhc);
00964 dig->nbytes += uhc;
00965 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), dig->nbytes);
00966 if (sigtag == RPMSIGTAG_SHA1)
00967 rpmtsOp(ts, RPMTS_OP_DIGEST)->count--;
00968 uh = headerFreeData(uh, uht);
00969 } break;
00970 case RPMSIGTAG_GPG:
00971 case RPMSIGTAG_PGP5:
00972 case RPMSIGTAG_PGP:
00973
00974 xx = pgpPrtPkts(sig, siglen, dig, (_print_pkts & rpmIsDebug()));
00975
00976 if (dig->signature.version != 3 && dig->signature.version != 4) {
00977 rpmMessage(RPMMESS_WARNING,
00978 _("only V3 and V4 signatures can be verified, skipping V%u signature\n"),
00979 dig->signature.version);
00980 rc = RPMRC_OK;
00981 goto exit;
00982 }
00983
00984 case RPMSIGTAG_MD5:
00985
00986 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
00987 while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), fd)) > 0)
00988 dig->nbytes += count;
00989 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), dig->nbytes);
00990 rpmtsOp(ts, RPMTS_OP_DIGEST)->count--;
00991 dig->nbytes += nb;
00992 if (count < 0) {
00993 rpmError(RPMERR_FREAD, _("%s: Fread failed: %s\n"),
00994 fn, Fstrerror(fd));
00995 rc = RPMRC_FAIL;
00996 goto exit;
00997 }
00998
00999
01000 for (i = fd->ndigests - 1; i >= 0; i--) {
01001 FDDIGEST_t fddig = fd->digests + i;
01002 if (fddig->hashctx != NULL)
01003 switch (fddig->hashalgo) {
01004 case PGPHASHALGO_MD5:
01005 dig->md5ctx = fddig->hashctx;
01006 fddig->hashctx = NULL;
01007 break;
01008 case PGPHASHALGO_SHA1:
01009 #if HAVE_BEECRYPT_API_H
01010 case PGPHASHALGO_SHA256:
01011 case PGPHASHALGO_SHA384:
01012 case PGPHASHALGO_SHA512:
01013 #endif
01014 dig->sha1ctx = fddig->hashctx;
01015 fddig->hashctx = NULL;
01016 break;
01017 default:
01018 break;
01019 }
01020 }
01021 break;
01022 }
01023
01026
01027 buf[0] = '\0';
01028
01029 rc = rpmVerifySignature(ts, buf);
01030 switch (rc) {
01031 case RPMRC_OK:
01032 rpmMessage(RPMMESS_DEBUG, "%s: %s", fn, buf);
01033 break;
01034 case RPMRC_NOTTRUSTED:
01035 case RPMRC_NOKEY:
01036
01037 { int lvl = (rpmtsStashKeyid(ts) ? RPMMESS_DEBUG : RPMMESS_WARNING);
01038 rpmMessage(lvl, "%s: %s", fn, buf);
01039 } break;
01040 case RPMRC_NOTFOUND:
01041 rpmMessage(RPMMESS_WARNING, "%s: %s", fn, buf);
01042 break;
01043 default:
01044 case RPMRC_FAIL:
01045 rpmMessage(RPMMESS_ERROR, "%s: %s", fn, buf);
01046 break;
01047 }
01048
01049 exit:
01050 if (rc != RPMRC_FAIL && h != NULL && hdrp != NULL) {
01051
01052 legacyRetrofit(h, l);
01053
01054
01055 headerMergeLegacySigs(h, sigh);
01056
01057
01058
01059 *hdrp = headerLink(h);
01060
01061 }
01062 h = headerFree(h);
01063 rpmtsCleanDig(ts);
01064 sigh = rpmFreeSignature(sigh);
01065 return rc;
01066 }
01067