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