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 #ifdef NOTYET
00467 case RPMTAG_RSAHEADER:
00468 #endif
00469 case RPMTAG_DSAHEADER:
00470 if (vsflags & RPMVSF_NODSAHEADER)
00471 break;
00472 if (entry->info.type != RPM_BIN_TYPE) {
00473 (void) snprintf(buf, sizeof(buf), _("hdr DSA: BAD, not binary\n"));
00474 goto exit;
00475 }
00476
00477 *info = entry->info;
00478
00479 siglen = info->count;
00480 break;
00481 default:
00482 break;
00483 }
00484 }
00485 rc = RPMRC_NOTFOUND;
00486
00487 exit:
00488
00489 if (rc != RPMRC_NOTFOUND) {
00490
00491 buf[sizeof(buf)-1] = '\0';
00492 if (msg) *msg = xstrdup(buf);
00493
00494 hclvl--;
00495 return rc;
00496 }
00497
00498
00499 if (info->tag == 0) {
00500 verifyinfo_exit:
00501 xx = headerVerifyInfo(ril-1, dl, pe+1, &entry->info, 0);
00502 if (xx != -1) {
00503 (void) snprintf(buf, sizeof(buf),
00504 _("tag[%d]: BAD, tag %d type %d offset %d count %d\n"),
00505 xx+1, entry->info.tag, entry->info.type,
00506 entry->info.offset, entry->info.count);
00507 rc = RPMRC_FAIL;
00508 } else {
00509 (void) snprintf(buf, sizeof(buf), "Header sanity check: OK\n");
00510 rc = RPMRC_OK;
00511 }
00512
00513 buf[sizeof(buf)-1] = '\0';
00514 if (msg) *msg = xstrdup(buf);
00515
00516 hclvl--;
00517 return rc;
00518 }
00519
00520
00521 dig = rpmtsDig(ts);
00522 if (dig == NULL)
00523 goto verifyinfo_exit;
00524 dig->nbytes = 0;
00525
00526
00527 sig = memcpy(xmalloc(siglen), dataStart + info->offset, siglen);
00528
00529 (void) rpmtsSetSig(ts, info->tag, info->type, sig, info->count);
00530
00531 switch (info->tag) {
00532 #ifdef NOTYET
00533 case RPMTAG_RSAHEADER:
00534
00535 xx = pgpPrtPkts(sig, info->count, dig, (_print_pkts & rpmIsDebug()));
00536
00537 if (dig->signature.version != 3) {
00538 rpmMessage(RPMMESS_WARNING,
00539 _("only V3 signatures can be verified, skipping V%u signature\n"),
00540 dig->signature.version);
00541 rpmtsCleanDig(ts);
00542 goto verifyinfo_exit;
00543 }
00544
00545 ildl[0] = htonl(ril);
00546 ildl[1] = (regionEnd - dataStart);
00547 ildl[1] = htonl(ildl[1]);
00548
00549 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
00550 dig->hdrmd5ctx = rpmDigestInit(PGPHASHALGO_MD5, RPMDIGEST_NONE);
00551
00552 b = (unsigned char *) header_magic;
00553 nb = sizeof(header_magic);
00554 (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb);
00555 dig->nbytes += nb;
00556
00557 b = (unsigned char *) ildl;
00558 nb = sizeof(ildl);
00559 (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb);
00560 dig->nbytes += nb;
00561
00562 b = (unsigned char *) pe;
00563 nb = (htonl(ildl[0]) * sizeof(*pe));
00564 (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb);
00565 dig->nbytes += nb;
00566
00567 b = (unsigned char *) dataStart;
00568 nb = htonl(ildl[1]);
00569 (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb);
00570 dig->nbytes += nb;
00571 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), dig->nbytes);
00572
00573 break;
00574 #endif
00575 case RPMTAG_DSAHEADER:
00576
00577 xx = pgpPrtPkts(sig, info->count, dig, (_print_pkts & rpmIsDebug()));
00578
00579 if (dig->signature.version != 3) {
00580 rpmMessage(RPMMESS_WARNING,
00581 _("only V3 signatures can be verified, skipping V%u signature\n"),
00582 dig->signature.version);
00583 rpmtsCleanDig(ts);
00584 goto verifyinfo_exit;
00585 }
00586
00587 case RPMTAG_SHA1HEADER:
00588
00589 ildl[0] = htonl(ril);
00590 ildl[1] = (regionEnd - dataStart);
00591 ildl[1] = htonl(ildl[1]);
00592
00593
00594 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
00595 dig->hdrsha1ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
00596
00597 b = (unsigned char *) header_magic;
00598 nb = sizeof(header_magic);
00599 (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
00600 dig->nbytes += nb;
00601
00602 b = (unsigned char *) ildl;
00603 nb = sizeof(ildl);
00604 (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
00605 dig->nbytes += nb;
00606
00607 b = (unsigned char *) pe;
00608 nb = (htonl(ildl[0]) * sizeof(*pe));
00609 (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
00610 dig->nbytes += nb;
00611
00612 b = (unsigned char *) dataStart;
00613 nb = htonl(ildl[1]);
00614 (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
00615 dig->nbytes += nb;
00616 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), dig->nbytes);
00617
00618 break;
00619 default:
00620 sig = _free(sig);
00621 break;
00622 }
00623
00624
00625 buf[0] = '\0';
00626
00627 rc = rpmVerifySignature(ts, buf);
00628
00629
00630 buf[sizeof(buf)-1] = '\0';
00631 if (msg) *msg = xstrdup(buf);
00632
00633
00634
00635 if (hclvl == 1)
00636 rpmtsCleanDig(ts);
00637 if (info->tag == RPMTAG_SHA1HEADER)
00638 sig = _free(sig);
00639 hclvl--;
00640 return rc;
00641 }
00642
00643 rpmRC rpmReadHeader(rpmts ts, FD_t fd, Header *hdrp, const char ** msg)
00644 {
00645 char buf[BUFSIZ];
00646 int_32 block[4];
00647 int_32 il;
00648 int_32 dl;
00649 int_32 * ei = NULL;
00650 size_t uc;
00651 int_32 nb;
00652 Header h = NULL;
00653 rpmRC rc = RPMRC_FAIL;
00654 int xx;
00655
00656
00657 buf[0] = '\0';
00658
00659 if (hdrp)
00660 *hdrp = NULL;
00661 if (msg)
00662 *msg = NULL;
00663
00664
00665 memset(block, 0, sizeof(block));
00666 if ((xx = timedRead(fd, (char *)block, sizeof(block))) != sizeof(block)) {
00667 (void) snprintf(buf, sizeof(buf),
00668 _("hdr size(%d): BAD, read returned %d\n"), (int)sizeof(block), xx);
00669 goto exit;
00670 }
00671 if (memcmp(block, header_magic, sizeof(header_magic))) {
00672 (void) snprintf(buf, sizeof(buf), _("hdr magic: BAD\n"));
00673 goto exit;
00674 }
00675
00676 il = ntohl(block[2]);
00677
00678 if (hdrchkTags(il)) {
00679 (void) snprintf(buf, sizeof(buf),
00680 _("hdr tags: BAD, no. of tags(%d) out of range\n"), il);
00681
00682 goto exit;
00683 }
00684
00685 dl = ntohl(block[3]);
00686
00687 if (hdrchkData(dl)) {
00688 (void) snprintf(buf, sizeof(buf),
00689 _("hdr data: BAD, no. of bytes(%d) out of range\n"), dl);
00690 goto exit;
00691 }
00692
00693
00694 nb = (il * sizeof(struct entryInfo_s)) + dl;
00695
00696 uc = sizeof(il) + sizeof(dl) + nb;
00697 ei = xmalloc(uc);
00698
00699 ei[0] = block[2];
00700 ei[1] = block[3];
00701 if ((xx = timedRead(fd, (char *)&ei[2], nb)) != nb) {
00702 (void) snprintf(buf, sizeof(buf),
00703 _("hdr blob(%d): BAD, read returned %d\n"), nb, xx);
00704 goto exit;
00705 }
00706
00707
00708
00709 rc = headerCheck(ts, ei, uc, msg);
00710 if (rc != RPMRC_OK)
00711 goto exit;
00712
00713
00714 h = headerLoad(ei);
00715 if (h == NULL) {
00716 (void) snprintf(buf, sizeof(buf), _("hdr load: BAD\n"));
00717 goto exit;
00718 }
00719 h->flags |= HEADERFLAG_ALLOCATED;
00720 ei = NULL;
00721
00722 exit:
00723
00724 if (hdrp && h && rc == RPMRC_OK)
00725 *hdrp = headerLink(h);
00726
00727 ei = _free(ei);
00728 h = headerFree(h);
00729
00730
00731 if (msg != NULL && *msg == NULL && buf[0] != '\0') {
00732 buf[sizeof(buf)-1] = '\0';
00733 *msg = xstrdup(buf);
00734 }
00735
00736
00737 return rc;
00738 }
00739
00740
00741 rpmRC rpmReadPackageFile(rpmts ts, FD_t fd, const char * fn, Header * hdrp)
00742 {
00743 pgpDig dig;
00744 byte buf[8*BUFSIZ];
00745 ssize_t count;
00746 struct rpmlead * l = alloca(sizeof(*l));
00747 Header sigh = NULL;
00748 int_32 sigtag;
00749 int_32 sigtype;
00750 const void * sig;
00751 int_32 siglen;
00752 Header h = NULL;
00753 const char * msg;
00754 int hmagic;
00755 rpmVSFlags vsflags;
00756 rpmRC rc = RPMRC_FAIL;
00757 int xx;
00758 int i;
00759
00760 if (hdrp) *hdrp = NULL;
00761
00762 #ifdef DYING
00763 { struct stat st;
00764
00765 memset(&st, 0, sizeof(st));
00766
00767 (void) fstat(Fileno(fd), &st);
00768
00769 if (S_ISREG(st.st_mode) && st.st_size < sizeof(*l)) {
00770 rc = RPMRC_NOTFOUND;
00771 goto exit;
00772 }
00773 }
00774 #endif
00775
00776 memset(l, 0, sizeof(*l));
00777 rc = readLead(fd, l);
00778 if (rc != RPMRC_OK)
00779 goto exit;
00780
00781 switch (l->major) {
00782 case 1:
00783 rpmError(RPMERR_NEWPACKAGE,
00784 _("packaging version 1 is not supported by this version of RPM\n"));
00785 rc = RPMRC_NOTFOUND;
00786 goto exit;
00787 break;
00788 case 2:
00789 case 3:
00790 case 4:
00791 break;
00792 default:
00793 rpmError(RPMERR_NEWPACKAGE, _("only packaging with major numbers <= 4 "
00794 "is supported by this version of RPM\n"));
00795 rc = RPMRC_NOTFOUND;
00796 goto exit;
00797 break;
00798 }
00799
00800
00801 msg = NULL;
00802 rc = rpmReadSignature(fd, &sigh, l->signature_type, &msg);
00803 switch (rc) {
00804 default:
00805 rpmError(RPMERR_SIGGEN, _("%s: rpmReadSignature failed: %s"), fn,
00806 (msg && *msg ? msg : "\n"));
00807 msg = _free(msg);
00808 goto exit;
00809 break;
00810 case RPMRC_OK:
00811 if (sigh == NULL) {
00812 rpmError(RPMERR_SIGGEN, _("%s: No signature available\n"), fn);
00813 rc = RPMRC_FAIL;
00814 goto exit;
00815 }
00816 break;
00817 }
00818 msg = _free(msg);
00819
00820 #define _chk(_mask) (sigtag == 0 && !(vsflags & (_mask)))
00821
00822
00823 sigtag = 0;
00824 vsflags = rpmtsVSFlags(ts);
00825 #ifdef DYING
00826 if (_chk(RPMVSF_NODSAHEADER) && headerIsEntry(sigh, RPMSIGTAG_DSA))
00827 sigtag = RPMSIGTAG_DSA;
00828 if (_chk(RPMVSF_NORSAHEADER) && headerIsEntry(sigh, RPMSIGTAG_RSA))
00829 sigtag = RPMSIGTAG_RSA;
00830 #endif
00831 if (_chk(RPMVSF_NODSA|RPMVSF_NEEDPAYLOAD) &&
00832 headerIsEntry(sigh, RPMSIGTAG_GPG))
00833 {
00834 sigtag = RPMSIGTAG_GPG;
00835 fdInitDigest(fd, PGPHASHALGO_SHA1, 0);
00836 }
00837 if (_chk(RPMVSF_NORSA|RPMVSF_NEEDPAYLOAD) &&
00838 headerIsEntry(sigh, RPMSIGTAG_PGP))
00839 {
00840 sigtag = RPMSIGTAG_PGP;
00841 fdInitDigest(fd, PGPHASHALGO_MD5, 0);
00842 }
00843 #ifdef DYING
00844 if (_chk(RPMVSF_NOSHA1HEADER) && headerIsEntry(sigh, RPMSIGTAG_SHA1))
00845 sigtag = RPMSIGTAG_SHA1;
00846 #endif
00847 if (_chk(RPMVSF_NOMD5|RPMVSF_NEEDPAYLOAD) &&
00848 headerIsEntry(sigh, RPMSIGTAG_MD5))
00849 {
00850 sigtag = RPMSIGTAG_MD5;
00851 fdInitDigest(fd, PGPHASHALGO_MD5, 0);
00852 }
00853
00854
00855 h = NULL;
00856 msg = NULL;
00857 rc = rpmReadHeader(ts, fd, &h, &msg);
00858 if (rc != RPMRC_OK || h == NULL) {
00859 rpmError(RPMERR_FREAD, _("%s: headerRead failed: %s"), fn,
00860 (msg && *msg ? msg : "\n"));
00861 msg = _free(msg);
00862 goto exit;
00863 }
00864 msg = _free(msg);
00865
00866
00867 if (sigtag == 0) {
00868 rc = RPMRC_OK;
00869 goto exit;
00870 }
00871
00872 dig = rpmtsDig(ts);
00873 if (dig == NULL) {
00874 rc = RPMRC_FAIL;
00875 goto exit;
00876 }
00877 dig->nbytes = 0;
00878
00879
00880 sig = NULL;
00881 xx = headerGetEntry(sigh, sigtag, &sigtype, (void **) &sig, &siglen);
00882 if (sig == NULL) {
00883 rc = RPMRC_FAIL;
00884 goto exit;
00885 }
00886 (void) rpmtsSetSig(ts, sigtag, sigtype, sig, siglen);
00887
00888 switch (sigtag) {
00889 case RPMSIGTAG_RSA:
00890
00891 xx = pgpPrtPkts(sig, siglen, dig, (_print_pkts & rpmIsDebug()));
00892
00893 if (dig->signature.version != 3) {
00894 rpmMessage(RPMMESS_WARNING,
00895 _("only V3 signatures can be verified, skipping V%u signature\n"),
00896 dig->signature.version);
00897 rc = RPMRC_OK;
00898 goto exit;
00899 }
00900 { void * uh = NULL;
00901 int_32 uht;
00902 int_32 uhc;
00903
00904 if (!headerGetEntry(h, RPMTAG_HEADERIMMUTABLE, &uht, &uh, &uhc))
00905 break;
00906 dig->md5ctx = rpmDigestInit(PGPHASHALGO_MD5, RPMDIGEST_NONE);
00907 (void) rpmDigestUpdate(dig->md5ctx, header_magic, sizeof(header_magic));
00908 dig->nbytes += sizeof(header_magic);
00909 (void) rpmDigestUpdate(dig->md5ctx, uh, uhc);
00910 dig->nbytes += uhc;
00911 uh = headerFreeData(uh, uht);
00912 } break;
00913 case RPMSIGTAG_DSA:
00914
00915 xx = pgpPrtPkts(sig, siglen, dig, (_print_pkts & rpmIsDebug()));
00916
00917 if (dig->signature.version != 3) {
00918 rpmMessage(RPMMESS_WARNING,
00919 _("only V3 signatures can be verified, skipping V%u signature\n"),
00920 dig->signature.version);
00921 rc = RPMRC_OK;
00922 goto exit;
00923 }
00924
00925 case RPMSIGTAG_SHA1:
00926 { void * uh = NULL;
00927 int_32 uht;
00928 int_32 uhc;
00929
00930 if (!headerGetEntry(h, RPMTAG_HEADERIMMUTABLE, &uht, &uh, &uhc))
00931 break;
00932 dig->hdrsha1ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
00933 (void) rpmDigestUpdate(dig->hdrsha1ctx, header_magic, sizeof(header_magic));
00934 dig->nbytes += sizeof(header_magic);
00935 (void) rpmDigestUpdate(dig->hdrsha1ctx, uh, uhc);
00936 dig->nbytes += uhc;
00937 uh = headerFreeData(uh, uht);
00938 } break;
00939 case RPMSIGTAG_GPG:
00940 case RPMSIGTAG_PGP5:
00941 case RPMSIGTAG_PGP:
00942
00943 xx = pgpPrtPkts(sig, siglen, dig,
00944 (_print_pkts & rpmIsDebug()));
00945
00946
00947 if (dig->signature.version != 3) {
00948 rpmMessage(RPMMESS_WARNING,
00949 _("only V3 signatures can be verified, skipping V%u signature\n"),
00950 dig->signature.version);
00951 rc = RPMRC_OK;
00952 goto exit;
00953 }
00954
00955 case RPMSIGTAG_MD5:
00956
00957 hmagic = ((l->major >= 3) ? HEADER_MAGIC_YES : HEADER_MAGIC_NO);
00958 dig->nbytes += headerSizeof(h, hmagic);
00959 while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), fd)) > 0)
00960 dig->nbytes += count;
00961 if (count < 0) {
00962 rpmError(RPMERR_FREAD, _("%s: Fread failed: %s\n"),
00963 fn, Fstrerror(fd));
00964 rc = RPMRC_FAIL;
00965 goto exit;
00966 }
00967 dig->nbytes += count;
00968
00969
00970 for (i = fd->ndigests - 1; i >= 0; i--) {
00971 FDDIGEST_t fddig = fd->digests + i;
00972 if (fddig->hashctx == NULL)
00973 continue;
00974 if (fddig->hashalgo == PGPHASHALGO_MD5) {
00975 dig->md5ctx = fddig->hashctx;
00976 fddig->hashctx = NULL;
00977 continue;
00978 }
00979 if (fddig->hashalgo == PGPHASHALGO_SHA1) {
00980 dig->sha1ctx = fddig->hashctx;
00981 fddig->hashctx = NULL;
00982 continue;
00983 }
00984 }
00985 break;
00986 }
00987
00990
00991 buf[0] = '\0';
00992
00993 rc = rpmVerifySignature(ts, buf);
00994 switch (rc) {
00995 case RPMRC_OK:
00996 rpmMessage(RPMMESS_DEBUG, "%s: %s", fn, buf);
00997 break;
00998 case RPMRC_NOTTRUSTED:
00999 case RPMRC_NOKEY:
01000
01001 { int lvl = (rpmtsStashKeyid(ts) ? RPMMESS_DEBUG : RPMMESS_WARNING);
01002 rpmMessage(lvl, "%s: %s", fn, buf);
01003 } break;
01004 case RPMRC_NOTFOUND:
01005 rpmMessage(RPMMESS_WARNING, "%s: %s", fn, buf);
01006 break;
01007 default:
01008 case RPMRC_FAIL:
01009 rpmMessage(RPMMESS_ERROR, "%s: %s", fn, buf);
01010 break;
01011 }
01012
01013 exit:
01014 if (rc != RPMRC_FAIL && h != NULL && hdrp != NULL) {
01015
01016 legacyRetrofit(h, l);
01017
01018
01019 headerMergeLegacySigs(h, sigh);
01020
01021
01022
01023 *hdrp = headerLink(h);
01024
01025 }
01026 h = headerFree(h);
01027 rpmtsCleanDig(ts);
01028 sigh = rpmFreeSignature(sigh);
01029 return rc;
01030 }
01031