00001
00005 #include "system.h"
00006
00007 #include <netinet/in.h>
00008
00009 #include <rpmio_internal.h>
00010 #include <rpmlib.h>
00011
00012 #if defined(RPM_VENDOR_MANDRIVA)
00013 #define _RPMEVR_INTERNAL
00014 #include "rpmevr.h"
00015 #endif
00016
00017 #include "rpmts.h"
00018 #include "rpmevr.h"
00019
00020 #include "misc.h"
00021 #include "rpmlead.h"
00022
00023 #include "header_internal.h"
00024 #include "signature.h"
00025 #include "debug.h"
00026
00027 #define alloca_strdup(_s) strcpy(alloca(strlen(_s)+1), (_s))
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 static int _print_pkts = 0;
00038
00039
00040 static unsigned int nkeyids_max = 256;
00041
00042 static unsigned int nkeyids = 0;
00043
00044 static unsigned int nextkeyid = 0;
00045
00046 static unsigned int * keyids;
00047
00048
00049 static unsigned char header_magic[8] = {
00050 0x8e, 0xad, 0xe8, 0x01, 0x00, 0x00, 0x00, 0x00
00051 };
00052
00056
00057 static int typeAlign[16] = {
00058 1,
00059 1,
00060 1,
00061 2,
00062 4,
00063 8,
00064 1,
00065 1,
00066 1,
00067 1,
00068 0,
00069 0,
00070 0,
00071 0,
00072 0,
00073 0
00074 };
00075
00080 #define hdrchkTags(_ntags) ((_ntags) & 0xffff0000)
00081
00085 #define hdrchkType(_type) ((_type) < RPM_MIN_TYPE || (_type) > RPM_MAX_TYPE)
00086
00091 #define hdrchkData(_nbytes) ((_nbytes) & 0xff000000)
00092
00096 #define hdrchkAlign(_type, _off) ((_off) & (typeAlign[_type]-1))
00097
00101 #define hdrchkRange(_dl, _off) ((_off) < 0 || (_off) > (_dl))
00102
00103 #if defined(RPM_VENDOR_MANDRIVA)
00104
00105 static int dncmp(const void * a, const void * b)
00106
00107 {
00108 const char *const * first = a;
00109 const char *const * second = b;
00110 return strcmp(*first, *second);
00111 }
00112
00113
00114
00119 static void compressFilelist(Header h)
00120
00121 {
00122 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00123 HAE_t hae = (HAE_t)headerAddEntry;
00124 HRE_t hre = (HRE_t)headerRemoveEntry;
00125 HFD_t hfd = headerFreeData;
00126 char ** fileNames;
00127 const char ** dirNames;
00128 const char ** baseNames;
00129 int_32 * dirIndexes;
00130 rpmTagType fnt;
00131 int count;
00132 int i, xx;
00133 int dirIndex = -1;
00134
00135
00136
00137
00138
00139
00140
00141 if (headerIsEntry(h, RPMTAG_DIRNAMES)) {
00142 xx = hre(h, RPMTAG_OLDFILENAMES);
00143 return;
00144 }
00145
00146 if (!hge(h, RPMTAG_OLDFILENAMES, &fnt, (void **) &fileNames, &count))
00147 return;
00148 if (fileNames == NULL || count <= 0)
00149 return;
00150
00151 dirNames = alloca(sizeof(*dirNames) * count);
00152 baseNames = alloca(sizeof(*dirNames) * count);
00153 dirIndexes = alloca(sizeof(*dirIndexes) * count);
00154
00155 if (fileNames[0][0] != '/') {
00156
00157 dirIndex = 0;
00158 dirNames[dirIndex] = "";
00159 for (i = 0; i < count; i++) {
00160 dirIndexes[i] = dirIndex;
00161 baseNames[i] = fileNames[i];
00162 }
00163 goto exit;
00164 }
00165
00166
00167 for (i = 0; i < count; i++) {
00168 const char ** needle;
00169 char savechar;
00170 char * baseName;
00171 int len;
00172
00173 if (fileNames[i] == NULL)
00174 continue;
00175 baseName = strrchr(fileNames[i], '/') + 1;
00176 len = baseName - fileNames[i];
00177 needle = dirNames;
00178 savechar = *baseName;
00179 *baseName = '\0';
00180
00181 if (dirIndex < 0 ||
00182 (needle = bsearch(&fileNames[i], dirNames, dirIndex + 1, sizeof(dirNames[0]), dncmp)) == NULL) {
00183 char *s = alloca(len + 1);
00184 memcpy(s, fileNames[i], len + 1);
00185 s[len] = '\0';
00186 dirIndexes[i] = ++dirIndex;
00187 dirNames[dirIndex] = s;
00188 } else
00189 dirIndexes[i] = needle - dirNames;
00190
00191
00192 *baseName = savechar;
00193 baseNames[i] = baseName;
00194 }
00195
00196
00197 exit:
00198 if (count > 0) {
00199 xx = hae(h, RPMTAG_DIRINDEXES, RPM_INT32_TYPE, dirIndexes, count);
00200 xx = hae(h, RPMTAG_BASENAMES, RPM_STRING_ARRAY_TYPE,
00201 baseNames, count);
00202 xx = hae(h, RPMTAG_DIRNAMES, RPM_STRING_ARRAY_TYPE,
00203 dirNames, dirIndex + 1);
00204 }
00205
00206 fileNames = hfd(fileNames, fnt);
00207
00208 xx = hre(h, RPMTAG_OLDFILENAMES);
00209 }
00210
00211
00212
00213
00214 static void providePackageNVR(Header h)
00215
00216 {
00217 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00218 HFD_t hfd = headerFreeData;
00219 const char *name, *version, *release;
00220 int_32 * epoch;
00221 const char *pEVR;
00222 char *p;
00223 int_32 pFlags = RPMSENSE_EQUAL;
00224 const char ** provides = NULL;
00225 const char ** providesEVR = NULL;
00226 rpmTagType pnt, pvt;
00227 int_32 * provideFlags = NULL;
00228 int providesCount;
00229 int i, xx;
00230 int bingo = 1;
00231
00232
00233 xx = headerNVR(h, &name, &version, &release);
00234 if (!(name && version && release))
00235 return;
00236 pEVR = p = alloca(21 + strlen(version) + 1 + strlen(release) + 1);
00237 *p = '\0';
00238 if (hge(h, RPMTAG_EPOCH, NULL, (void **) &epoch, NULL)) {
00239 sprintf(p, "%d:", *epoch);
00240 while (*p != '\0')
00241 p++;
00242 }
00243 (void) stpcpy( stpcpy( stpcpy(p, version) , "-") , release);
00244
00245
00246
00247
00248
00249 if (!hge(h, RPMTAG_PROVIDENAME, &pnt, (void **) &provides, &providesCount))
00250 goto exit;
00251
00252
00253
00254
00255 if (!hge(h, RPMTAG_PROVIDEVERSION, &pvt, (void **) &providesEVR, NULL)) {
00256 for (i = 0; i < providesCount; i++) {
00257 char * vdummy = "";
00258 int_32 fdummy = RPMSENSE_ANY;
00259 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEVERSION, RPM_STRING_ARRAY_TYPE,
00260 &vdummy, 1);
00261 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEFLAGS, RPM_INT32_TYPE,
00262 &fdummy, 1);
00263 }
00264 goto exit;
00265 }
00266
00267 xx = hge(h, RPMTAG_PROVIDEFLAGS, NULL, (void **) &provideFlags, NULL);
00268
00269
00270 if (provides && providesEVR && provideFlags)
00271 for (i = 0; i < providesCount; i++) {
00272 if (!(provides[i] && providesEVR[i]))
00273 continue;
00274 if (!(provideFlags[i] == RPMSENSE_EQUAL &&
00275 !strcmp(name, provides[i]) && !strcmp(pEVR, providesEVR[i])))
00276 continue;
00277 bingo = 0;
00278 break;
00279 }
00280
00281
00282 exit:
00283 provides = hfd(provides, pnt);
00284 providesEVR = hfd(providesEVR, pvt);
00285
00286 if (bingo) {
00287 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDENAME, RPM_STRING_ARRAY_TYPE,
00288 &name, 1);
00289 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEFLAGS, RPM_INT32_TYPE,
00290 &pFlags, 1);
00291 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEVERSION, RPM_STRING_ARRAY_TYPE,
00292 &pEVR, 1);
00293 }
00294 }
00295
00296 static void add_RPMTAG_SOURCERPM(Header h)
00297 {
00298 if (!headerIsEntry(h, RPMTAG_SOURCERPM) && !headerIsEntry(h, RPMTAG_SOURCEPACKAGE)) {
00299
00300
00301 headerAddEntry(h, RPMTAG_SOURCERPM, RPM_STRING_TYPE, "\0", 1);
00302 }
00303 }
00304
00305
00306 static void rpm3to4(Header h) {
00307 char * rpmversion;
00308 rpmTagType rpmversion_type;
00309
00310 (void) headerGetEntry(h, RPMTAG_RPMVERSION, NULL, (void **) &rpmversion, &rpmversion_type);
00311
00312 if ((!rpmversion) || rpmversion[0] < '4') {
00313 add_RPMTAG_SOURCERPM(h);
00314 providePackageNVR(h);
00315 compressFilelist(h);
00316 }
00317 headerFreeTag(h, (void *) rpmversion, rpmversion_type);
00318 return;
00319 }
00320 #endif
00321
00322
00323 static int dncmp(const void * a, const void * b)
00324
00325 {
00326 const char *const * first = a;
00327 const char *const * second = b;
00328 return strcmp(*first, *second);
00329 }
00330
00331
00332
00337 static void compressFilelist(Header h)
00338
00339 {
00340 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00341 HAE_t hae = (HAE_t)headerAddEntry;
00342 HRE_t hre = (HRE_t)headerRemoveEntry;
00343 HFD_t hfd = headerFreeData;
00344 char ** fileNames;
00345 const char ** dirNames;
00346 const char ** baseNames;
00347 int_32 * dirIndexes;
00348 rpmTagType fnt;
00349 int count;
00350 int i, xx;
00351 int dirIndex = -1;
00352
00353
00354
00355
00356
00357
00358
00359 if (headerIsEntry(h, RPMTAG_DIRNAMES)) {
00360 xx = hre(h, RPMTAG_OLDFILENAMES);
00361 return;
00362 }
00363
00364 if (!hge(h, RPMTAG_OLDFILENAMES, &fnt, (void **) &fileNames, &count))
00365 return;
00366 if (fileNames == NULL || count <= 0)
00367 return;
00368
00369 dirNames = alloca(sizeof(*dirNames) * count);
00370 baseNames = alloca(sizeof(*dirNames) * count);
00371 dirIndexes = alloca(sizeof(*dirIndexes) * count);
00372
00373 if (fileNames[0][0] != '/') {
00374
00375 dirIndex = 0;
00376 dirNames[dirIndex] = "";
00377 for (i = 0; i < count; i++) {
00378 dirIndexes[i] = dirIndex;
00379 baseNames[i] = fileNames[i];
00380 }
00381 goto exit;
00382 }
00383
00384
00385 for (i = 0; i < count; i++) {
00386 const char ** needle;
00387 char savechar;
00388 char * baseName;
00389 int len;
00390
00391 if (fileNames[i] == NULL)
00392 continue;
00393 baseName = strrchr(fileNames[i], '/') + 1;
00394 len = baseName - fileNames[i];
00395 needle = dirNames;
00396 savechar = *baseName;
00397 *baseName = '\0';
00398
00399 if (dirIndex < 0 ||
00400 (needle = bsearch(&fileNames[i], dirNames, dirIndex + 1, sizeof(dirNames[0]), dncmp)) == NULL) {
00401 char *s = alloca(len + 1);
00402 memcpy(s, fileNames[i], len + 1);
00403 s[len] = '\0';
00404 dirIndexes[i] = ++dirIndex;
00405 dirNames[dirIndex] = s;
00406 } else
00407 dirIndexes[i] = needle - dirNames;
00408
00409
00410 *baseName = savechar;
00411 baseNames[i] = baseName;
00412 }
00413
00414
00415 exit:
00416 if (count > 0) {
00417 xx = hae(h, RPMTAG_DIRINDEXES, RPM_INT32_TYPE, dirIndexes, count);
00418 xx = hae(h, RPMTAG_BASENAMES, RPM_STRING_ARRAY_TYPE,
00419 baseNames, count);
00420 xx = hae(h, RPMTAG_DIRNAMES, RPM_STRING_ARRAY_TYPE,
00421 dirNames, dirIndex + 1);
00422 }
00423
00424 fileNames = hfd(fileNames, fnt);
00425
00426 xx = hre(h, RPMTAG_OLDFILENAMES);
00427 }
00428
00429
00430
00431 static void rpm3to4(Header h) {
00432 char * rpmversion;
00433 int_32 rpmversion_type;
00434
00435 (void) headerGetEntry(h, RPMTAG_RPMVERSION, NULL, (void **) &rpmversion, &rpmversion_type);
00436
00437 if ((!rpmversion) || rpmversion[0] < '4') {
00438 int *epoch;
00439 const char * name, *version, *release;
00440 const char *pEVR;
00441 char *p;
00442 int_32 pFlags = RPMSENSE_EQUAL;
00443
00444 if (headerNVR(h, &name, &version, &release) == 0) {
00445 pEVR = p = alloca(21 + strlen(version) + 1 + strlen(release) + 1);
00446 *p = '\0';
00447 if (headerGetEntry(h, RPMTAG_EPOCH, NULL, (void **) &epoch, NULL)) {
00448 sprintf(p, "%d:", *epoch);
00449 while (*p != '\0')
00450 p++;
00451 }
00452 (void) stpcpy( stpcpy( stpcpy(p, version) , "-") , release);
00453
00454 headerAddOrAppendEntry(h, RPMTAG_PROVIDENAME, RPM_STRING_ARRAY_TYPE, &name, 1);
00455 headerAddOrAppendEntry(h, RPMTAG_PROVIDEFLAGS, RPM_INT32_TYPE, &pFlags, 1);
00456 headerAddOrAppendEntry(h, RPMTAG_PROVIDEVERSION, RPM_STRING_ARRAY_TYPE, &pEVR, 1);
00457 }
00458 compressFilelist(h);
00459 }
00460 headerFreeTag(h, (void *) rpmversion, rpmversion_type);
00461 return;
00462 }
00463
00464 void headerMergeLegacySigs(Header h, const Header sigh)
00465 {
00466 HFD_t hfd = (HFD_t) headerFreeData;
00467 HAE_t hae = (HAE_t) headerAddEntry;
00468 HeaderIterator hi;
00469 int_32 tag, type, count;
00470 const void * ptr;
00471 int xx;
00472
00473 for (hi = headerInitIterator(sigh);
00474 headerNextIterator(hi, &tag, &type, &ptr, &count);
00475 ptr = hfd(ptr, type))
00476 {
00477 switch (tag) {
00478
00479 case RPMSIGTAG_SIZE:
00480 tag = RPMTAG_SIGSIZE;
00481 break;
00482 case RPMSIGTAG_LEMD5_1:
00483 tag = RPMTAG_SIGLEMD5_1;
00484 break;
00485 case RPMSIGTAG_PGP:
00486 tag = RPMTAG_SIGPGP;
00487 break;
00488 case RPMSIGTAG_LEMD5_2:
00489 tag = RPMTAG_SIGLEMD5_2;
00490 break;
00491 case RPMSIGTAG_MD5:
00492 tag = RPMTAG_SIGMD5;
00493 break;
00494 case RPMSIGTAG_GPG:
00495 tag = RPMTAG_SIGGPG;
00496 break;
00497 case RPMSIGTAG_PGP5:
00498 tag = RPMTAG_SIGPGP5;
00499 break;
00500 case RPMSIGTAG_PAYLOADSIZE:
00501 tag = RPMTAG_ARCHIVESIZE;
00502 break;
00503 case RPMSIGTAG_SHA1:
00504 case RPMSIGTAG_DSA:
00505 case RPMSIGTAG_RSA:
00506 default:
00507 if (!(tag >= HEADER_SIGBASE && tag < HEADER_TAGBASE))
00508 continue;
00509 break;
00510 }
00511 if (ptr == NULL) continue;
00512 if (!headerIsEntry(h, tag)) {
00513 if (hdrchkType(type))
00514 continue;
00515 if (count < 0 || hdrchkData(count))
00516 continue;
00517 switch(type) {
00518 case RPM_NULL_TYPE:
00519 continue;
00520 break;
00521 case RPM_CHAR_TYPE:
00522 case RPM_INT8_TYPE:
00523 case RPM_INT16_TYPE:
00524 case RPM_INT32_TYPE:
00525 if (count != 1)
00526 continue;
00527 break;
00528 case RPM_STRING_TYPE:
00529 case RPM_BIN_TYPE:
00530 if (count >= 16*1024)
00531 continue;
00532 break;
00533 case RPM_STRING_ARRAY_TYPE:
00534 case RPM_I18NSTRING_TYPE:
00535 continue;
00536 break;
00537 }
00538 xx = hae(h, tag, type, ptr, count);
00539 }
00540 }
00541 hi = headerFreeIterator(hi);
00542 }
00543
00544 Header headerRegenSigHeader(const Header h, int noArchiveSize)
00545 {
00546 HFD_t hfd = (HFD_t) headerFreeData;
00547 Header sigh = rpmNewSignature();
00548 HeaderIterator hi;
00549 int_32 tag, stag, type, count;
00550 const void * ptr;
00551 int xx;
00552
00553 for (hi = headerInitIterator(h);
00554 headerNextIterator(hi, &tag, &type, &ptr, &count);
00555 ptr = hfd(ptr, type))
00556 {
00557 switch (tag) {
00558
00559 case RPMTAG_SIGSIZE:
00560 stag = RPMSIGTAG_SIZE;
00561 break;
00562 case RPMTAG_SIGLEMD5_1:
00563 stag = RPMSIGTAG_LEMD5_1;
00564 break;
00565 case RPMTAG_SIGPGP:
00566 stag = RPMSIGTAG_PGP;
00567 break;
00568 case RPMTAG_SIGLEMD5_2:
00569 stag = RPMSIGTAG_LEMD5_2;
00570 break;
00571 case RPMTAG_SIGMD5:
00572 stag = RPMSIGTAG_MD5;
00573 break;
00574 case RPMTAG_SIGGPG:
00575 stag = RPMSIGTAG_GPG;
00576 break;
00577 case RPMTAG_SIGPGP5:
00578 stag = RPMSIGTAG_PGP5;
00579 break;
00580 case RPMTAG_ARCHIVESIZE:
00581
00582 if (noArchiveSize)
00583 continue;
00584 stag = RPMSIGTAG_PAYLOADSIZE;
00585 break;
00586 case RPMTAG_SHA1HEADER:
00587 case RPMTAG_DSAHEADER:
00588 case RPMTAG_RSAHEADER:
00589 default:
00590 if (!(tag >= HEADER_SIGBASE && tag < HEADER_TAGBASE))
00591 continue;
00592 stag = tag;
00593 break;
00594 }
00595 if (ptr == NULL) continue;
00596 if (!headerIsEntry(sigh, stag))
00597 xx = headerAddEntry(sigh, stag, type, ptr, count);
00598 }
00599 hi = headerFreeIterator(hi);
00600 return sigh;
00601 }
00602
00608 static int rpmtsStashKeyid(rpmts ts)
00609
00610
00611 {
00612 const void * sig = rpmtsSig(ts);
00613 pgpDig dig = rpmtsDig(ts);
00614 pgpDigParams sigp = rpmtsSignature(ts);
00615 unsigned int keyid;
00616 int i;
00617
00618 if (sig == NULL || dig == NULL || sigp == NULL)
00619 return 0;
00620
00621 keyid = pgpGrab(sigp->signid+4, 4);
00622 if (keyid == 0)
00623 return 0;
00624
00625 if (keyids != NULL)
00626 for (i = 0; i < nkeyids; i++) {
00627
00628 if (keyid == keyids[i])
00629 return 1;
00630
00631 }
00632
00633 if (nkeyids < nkeyids_max) {
00634 nkeyids++;
00635 keyids = xrealloc(keyids, nkeyids * sizeof(*keyids));
00636 }
00637
00638 if (keyids)
00639 keyids[nextkeyid] = keyid;
00640
00641 nextkeyid++;
00642 nextkeyid %= nkeyids_max;
00643
00644 return 0;
00645 }
00646
00647 int headerVerifyInfo(int il, int dl, const void * pev, void * iv, int negate)
00648 {
00649
00650 entryInfo pe = (entryInfo) pev;
00651
00652 entryInfo info = iv;
00653 int i;
00654
00655
00656 for (i = 0; i < il; i++) {
00657 info->tag = ntohl(pe[i].tag);
00658 info->type = ntohl(pe[i].type);
00659 info->offset = ntohl(pe[i].offset);
00660 if (negate)
00661 info->offset = -info->offset;
00662 info->count = ntohl(pe[i].count);
00663
00664 if (hdrchkType(info->type))
00665 return i;
00666 if (hdrchkAlign(info->type, info->offset))
00667 return i;
00668 if (!negate && hdrchkRange(dl, info->offset))
00669 return i;
00670 if (hdrchkData(info->count))
00671 return i;
00672
00673 }
00674
00675 return -1;
00676 }
00677
00691 rpmRC headerCheck(rpmts ts, const void * uh, size_t uc, const char ** msg)
00692 {
00693 pgpDig dig;
00694 unsigned char buf[8*BUFSIZ];
00695 int_32 * ei = (int_32 *) uh;
00696
00697 int_32 il = ntohl(ei[0]);
00698 int_32 dl = ntohl(ei[1]);
00699
00700 entryInfo pe = (entryInfo) &ei[2];
00701
00702
00703 int_32 ildl[2];
00704 int_32 pvlen = sizeof(ildl) + (il * sizeof(*pe)) + dl;
00705 unsigned char * dataStart = (unsigned char *) (pe + il);
00706 indexEntry entry = memset(alloca(sizeof(*entry)), 0, sizeof(*entry));
00707 entryInfo info = memset(alloca(sizeof(*info)), 0, sizeof(*info));
00708 const void * sig = NULL;
00709 const char * b;
00710 rpmVSFlags vsflags = rpmtsVSFlags(ts);
00711 int siglen = 0;
00712 int blen;
00713 size_t nb;
00714 int_32 ril = 0;
00715 unsigned char * regionEnd = NULL;
00716 rpmRC rc = RPMRC_FAIL;
00717 int xx;
00718 int i;
00719 static int hclvl;
00720
00721 hclvl++;
00722
00723 buf[0] = '\0';
00724
00725
00726
00727 if (uc > 0 && pvlen != uc) {
00728 (void) snprintf(buf, sizeof(buf),
00729 _("blob size(%d): BAD, 8 + 16 * il(%d) + dl(%d)\n"),
00730 (int)uc, (int)il, (int)dl);
00731 goto exit;
00732 }
00733
00734
00735 xx = headerVerifyInfo(1, dl, pe, &entry->info, 0);
00736 if (xx != -1) {
00737 (void) snprintf(buf, sizeof(buf),
00738 _("tag[%d]: BAD, tag %d type %d offset %d count %d\n"),
00739 0, entry->info.tag, entry->info.type,
00740 entry->info.offset, entry->info.count);
00741 goto exit;
00742 }
00743
00744
00745
00746 if (!(entry->info.tag == RPMTAG_HEADERIMMUTABLE
00747 && entry->info.type == RPM_BIN_TYPE
00748 && entry->info.count == REGION_TAG_COUNT))
00749 {
00750 rc = RPMRC_NOTFOUND;
00751 goto exit;
00752 }
00753
00754
00755
00756 if (entry->info.offset >= dl) {
00757 (void) snprintf(buf, sizeof(buf),
00758 _("region offset: BAD, tag %d type %d offset %d count %d\n"),
00759 entry->info.tag, entry->info.type,
00760 entry->info.offset, entry->info.count);
00761 goto exit;
00762 }
00763
00764
00765 regionEnd = dataStart + entry->info.offset;
00766
00767
00768 (void) memcpy(info, regionEnd, REGION_TAG_COUNT);
00769
00770 regionEnd += REGION_TAG_COUNT;
00771
00772 xx = headerVerifyInfo(1, dl, info, &entry->info, 1);
00773 if (xx != -1 ||
00774 !(entry->info.tag == RPMTAG_HEADERIMMUTABLE
00775 && entry->info.type == RPM_BIN_TYPE
00776 && entry->info.count == REGION_TAG_COUNT))
00777 {
00778 (void) snprintf(buf, sizeof(buf),
00779 _("region trailer: BAD, tag %d type %d offset %d count %d\n"),
00780 entry->info.tag, entry->info.type,
00781 entry->info.offset, entry->info.count);
00782 goto exit;
00783 }
00784
00785
00786 memset(info, 0, sizeof(*info));
00787
00788
00789
00790 ril = entry->info.offset/sizeof(*pe);
00791 if ((entry->info.offset % sizeof(*pe)) || ril > il) {
00792 (void) snprintf(buf, sizeof(buf),
00793 _("region size: BAD, ril(%d) > il(%d)\n"), ril, il);
00794 goto exit;
00795 }
00796
00797
00798 for (i = ril; i < il; i++) {
00799 xx = headerVerifyInfo(1, dl, pe+i, &entry->info, 0);
00800 if (xx != -1) {
00801 (void) snprintf(buf, sizeof(buf),
00802 _("tag[%d]: BAD, tag %d type %d offset %d count %d\n"),
00803 i, entry->info.tag, entry->info.type,
00804 entry->info.offset, entry->info.count);
00805 goto exit;
00806 }
00807
00808 switch (entry->info.tag) {
00809 case RPMTAG_SHA1HEADER:
00810 if (vsflags & RPMVSF_NOSHA1HEADER)
00811 break;
00812 blen = 0;
00813
00814 for (b = dataStart + entry->info.offset; *b != '\0'; b++) {
00815 if (strchr("0123456789abcdefABCDEF", *b) == NULL)
00816 break;
00817 blen++;
00818 }
00819 if (entry->info.type != RPM_STRING_TYPE || *b != '\0' || blen != 40)
00820 {
00821 (void) snprintf(buf, sizeof(buf), _("hdr SHA1: BAD, not hex\n"));
00822 goto exit;
00823 }
00824
00825 if (info->tag == 0) {
00826
00827 *info = entry->info;
00828
00829 siglen = blen + 1;
00830 }
00831 break;
00832 case RPMTAG_RSAHEADER:
00833 if (vsflags & RPMVSF_NORSAHEADER)
00834 break;
00835 if (entry->info.type != RPM_BIN_TYPE) {
00836 (void) snprintf(buf, sizeof(buf), _("hdr RSA: BAD, not binary\n"));
00837 goto exit;
00838 }
00839
00840 *info = entry->info;
00841
00842 siglen = info->count;
00843 break;
00844 case RPMTAG_DSAHEADER:
00845 if (vsflags & RPMVSF_NODSAHEADER)
00846 break;
00847 if (entry->info.type != RPM_BIN_TYPE) {
00848 (void) snprintf(buf, sizeof(buf), _("hdr DSA: BAD, not binary\n"));
00849 goto exit;
00850 }
00851
00852 *info = entry->info;
00853
00854 siglen = info->count;
00855 break;
00856 default:
00857 break;
00858 }
00859 }
00860 rc = RPMRC_NOTFOUND;
00861
00862 exit:
00863
00864 if (rc != RPMRC_NOTFOUND) {
00865
00866 buf[sizeof(buf)-1] = '\0';
00867 if (msg) *msg = xstrdup(buf);
00868
00869 hclvl--;
00870 return rc;
00871 }
00872
00873
00874 if (info->tag == 0) {
00875 verifyinfo_exit:
00876 xx = headerVerifyInfo(ril-1, dl, pe+1, &entry->info, 0);
00877 if (xx != -1) {
00878 (void) snprintf(buf, sizeof(buf),
00879 _("tag[%d]: BAD, tag %d type %d offset %d count %d\n"),
00880 xx+1, entry->info.tag, entry->info.type,
00881 entry->info.offset, entry->info.count);
00882 rc = RPMRC_FAIL;
00883 } else {
00884 (void) snprintf(buf, sizeof(buf), "Header sanity check: OK\n");
00885 rc = RPMRC_OK;
00886 }
00887
00888 buf[sizeof(buf)-1] = '\0';
00889 if (msg) *msg = xstrdup(buf);
00890
00891 hclvl--;
00892 return rc;
00893 }
00894
00895
00896 dig = rpmtsDig(ts);
00897 if (dig == NULL)
00898 goto verifyinfo_exit;
00899 dig->nbytes = 0;
00900
00901
00902 sig = memcpy(xmalloc(siglen), dataStart + info->offset, siglen);
00903
00904 (void) rpmtsSetSig(ts, info->tag, info->type, sig, info->count);
00905
00906 switch (info->tag) {
00907 case RPMTAG_RSAHEADER:
00908
00909 xx = pgpPrtPkts(sig, info->count, dig, (_print_pkts & rpmIsDebug()));
00910 if (dig->signature.version != 3 && dig->signature.version != 4) {
00911 rpmMessage(RPMMESS_ERROR,
00912 _("skipping header with unverifiable V%u signature\n"),
00913 dig->signature.version);
00914 rpmtsCleanDig(ts);
00915 rc = RPMRC_FAIL;
00916 goto exit;
00917 }
00918
00919 ildl[0] = htonl(ril);
00920 ildl[1] = (regionEnd - dataStart);
00921 ildl[1] = htonl(ildl[1]);
00922
00923 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
00924 dig->hdrmd5ctx = rpmDigestInit(dig->signature.hash_algo, RPMDIGEST_NONE);
00925
00926 b = (unsigned char *) header_magic;
00927 nb = sizeof(header_magic);
00928 (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb);
00929 dig->nbytes += nb;
00930
00931 b = (unsigned char *) ildl;
00932 nb = sizeof(ildl);
00933 (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb);
00934 dig->nbytes += nb;
00935
00936 b = (unsigned char *) pe;
00937 nb = (htonl(ildl[0]) * sizeof(*pe));
00938 (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb);
00939 dig->nbytes += nb;
00940
00941 b = (unsigned char *) dataStart;
00942 nb = htonl(ildl[1]);
00943 (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb);
00944 dig->nbytes += nb;
00945 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), dig->nbytes);
00946
00947 break;
00948 case RPMTAG_DSAHEADER:
00949
00950 xx = pgpPrtPkts(sig, info->count, dig, (_print_pkts & rpmIsDebug()));
00951 if (dig->signature.version != 3 && dig->signature.version != 4) {
00952 rpmMessage(RPMMESS_ERROR,
00953 _("skipping header with unverifiable V%u signature\n"),
00954 dig->signature.version);
00955 rpmtsCleanDig(ts);
00956 rc = RPMRC_FAIL;
00957 goto exit;
00958 }
00959
00960 case RPMTAG_SHA1HEADER:
00961
00962 ildl[0] = htonl(ril);
00963 ildl[1] = (regionEnd - dataStart);
00964 ildl[1] = htonl(ildl[1]);
00965
00966
00967 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
00968 dig->hdrsha1ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
00969
00970 b = (unsigned char *) header_magic;
00971 nb = sizeof(header_magic);
00972 (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
00973 dig->nbytes += nb;
00974
00975 b = (unsigned char *) ildl;
00976 nb = sizeof(ildl);
00977 (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
00978 dig->nbytes += nb;
00979
00980 b = (unsigned char *) pe;
00981 nb = (htonl(ildl[0]) * sizeof(*pe));
00982 (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
00983 dig->nbytes += nb;
00984
00985 b = (unsigned char *) dataStart;
00986 nb = htonl(ildl[1]);
00987 (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
00988 dig->nbytes += nb;
00989 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), dig->nbytes);
00990
00991 break;
00992 default:
00993 sig = _free(sig);
00994 break;
00995 }
00996
00997
00998 buf[0] = '\0';
00999
01000 rc = rpmVerifySignature(ts, buf);
01001
01002
01003 buf[sizeof(buf)-1] = '\0';
01004 if (msg) *msg = xstrdup(buf);
01005
01006
01007
01008 if (hclvl == 1)
01009 rpmtsCleanDig(ts);
01010 if (info->tag == RPMTAG_SHA1HEADER)
01011 sig = _free(sig);
01012 hclvl--;
01013 return rc;
01014 }
01015
01016 rpmRC rpmReadHeader(rpmts ts, FD_t fd, Header *hdrp, const char ** msg)
01017 {
01018 char buf[BUFSIZ];
01019 int_32 block[4];
01020 int_32 il;
01021 int_32 dl;
01022 int_32 * ei = NULL;
01023 size_t uc;
01024 size_t startoff;
01025 int_32 nb;
01026 Header h = NULL;
01027 const char * origin = NULL;
01028 rpmRC rc = RPMRC_FAIL;
01029 int xx;
01030
01031
01032 buf[0] = '\0';
01033
01034 if (hdrp)
01035 *hdrp = NULL;
01036 if (msg)
01037 *msg = NULL;
01038
01039
01040 startoff = fd->stats->ops[FDSTAT_READ].bytes;
01041 memset(block, 0, sizeof(block));
01042 if ((xx = timedRead(fd, (char *)block, sizeof(block))) != sizeof(block)) {
01043 (void) snprintf(buf, sizeof(buf),
01044 _("hdr size(%d): BAD, read returned %d\n"), (int)sizeof(block), xx);
01045 goto exit;
01046 }
01047 if (memcmp(block, header_magic, sizeof(header_magic))) {
01048 (void) snprintf(buf, sizeof(buf), _("hdr magic: BAD\n"));
01049 goto exit;
01050 }
01051
01052 il = ntohl(block[2]);
01053
01054 if (hdrchkTags(il)) {
01055 (void) snprintf(buf, sizeof(buf),
01056 _("hdr tags: BAD, no. of tags(%d) out of range\n"), il);
01057
01058 goto exit;
01059 }
01060
01061 dl = ntohl(block[3]);
01062
01063 if (hdrchkData(dl)) {
01064 (void) snprintf(buf, sizeof(buf),
01065 _("hdr data: BAD, no. of bytes(%d) out of range\n"), dl);
01066 goto exit;
01067 }
01068
01069
01070 nb = (il * sizeof(struct entryInfo_s)) + dl;
01071
01072 uc = sizeof(il) + sizeof(dl) + nb;
01073 ei = xmalloc(uc);
01074
01075 ei[0] = block[2];
01076 ei[1] = block[3];
01077 if ((xx = timedRead(fd, (char *)&ei[2], nb)) != nb) {
01078 (void) snprintf(buf, sizeof(buf),
01079 _("hdr blob(%d): BAD, read returned %d\n"), nb, xx);
01080 goto exit;
01081 }
01082
01083
01084
01085 rc = headerCheck(ts, ei, uc, msg);
01086 if (rc != RPMRC_OK)
01087 goto exit;
01088
01089
01090 h = headerLoad(ei);
01091 if (h == NULL) {
01092 (void) snprintf(buf, sizeof(buf), _("hdr load: BAD\n"));
01093 goto exit;
01094 }
01095 h->flags |= HEADERFLAG_ALLOCATED;
01096 ei = NULL;
01097
01098
01099 origin = fdGetOPath(fd);
01100 if (origin != NULL) {
01101 const char * lpath = NULL;
01102 int ut = urlPath(origin, &lpath);
01103 ut = ut;
01104 if (lpath && *lpath != '/') {
01105 char * rpath = Realpath(origin, NULL);
01106 (void) headerSetOrigin(h, rpath);
01107 rpath = _free(rpath);
01108 } else
01109 (void) headerSetOrigin(h, origin);
01110 }
01111 { struct stat * st = headerGetStatbuf(h);
01112 int saveno = errno;
01113 (void) fstat(Fileno(fd), st);
01114 errno = saveno;
01115 }
01116 (void) headerSetStartOff(h, startoff);
01117 (void) headerSetEndOff(h, fd->stats->ops[FDSTAT_READ].bytes);
01118
01119 exit:
01120
01121 if (hdrp && h && rc == RPMRC_OK)
01122 *hdrp = headerLink(h);
01123
01124 ei = _free(ei);
01125 h = headerFree(h);
01126
01127
01128 if (msg != NULL && *msg == NULL && buf[0] != '\0') {
01129 buf[sizeof(buf)-1] = '\0';
01130 *msg = xstrdup(buf);
01131 }
01132
01133
01134 return rc;
01135 }
01136
01137
01138 rpmRC rpmReadPackageFile(rpmts ts, FD_t fd, const char * fn, Header * hdrp)
01139 {
01140 pgpDig dig;
01141 byte buf[8*BUFSIZ];
01142 ssize_t count;
01143 struct rpmlead * l = alloca(sizeof(*l));
01144 Header sigh = NULL;
01145 int_32 sigtag;
01146 int_32 sigtype;
01147 const void * sig;
01148 int_32 siglen;
01149 rpmtsOpX opx;
01150 size_t nb;
01151 Header h = NULL;
01152 const char * msg;
01153 rpmVSFlags vsflags;
01154 rpmRC rc = RPMRC_FAIL;
01155 rpmop opsave = memset(alloca(sizeof(*opsave)), 0, sizeof(*opsave));
01156 int xx;
01157 int i;
01158
01159 if (hdrp) *hdrp = NULL;
01160
01161 #ifdef DYING
01162 { struct stat st;
01163
01164 memset(&st, 0, sizeof(st));
01165
01166 (void) fstat(Fileno(fd), &st);
01167
01168 if (S_ISREG(st.st_mode) && st.st_size < sizeof(*l)) {
01169 rc = RPMRC_NOTFOUND;
01170 goto exit;
01171 }
01172 }
01173 #endif
01174
01175
01176 (void) rpmswAdd(opsave, fdstat_op(fd, FDSTAT_READ));
01177
01178 memset(l, 0, sizeof(*l));
01179 rc = readLead(fd, l);
01180 if (rc != RPMRC_OK)
01181 goto exit;
01182
01183 switch (l->major) {
01184 case 1:
01185 rpmError(RPMERR_NEWPACKAGE,
01186 _("packaging version 1 is not supported by this version of RPM\n"));
01187 rc = RPMRC_NOTFOUND;
01188 goto exit;
01189 break;
01190 case 2:
01191 case 3:
01192 case 4:
01193 break;
01194 default:
01195 rpmError(RPMERR_NEWPACKAGE, _("only packaging with major numbers <= 4 "
01196 "is supported by this version of RPM\n"));
01197 rc = RPMRC_NOTFOUND;
01198 goto exit;
01199 break;
01200 }
01201
01202
01203 msg = NULL;
01204 rc = rpmReadSignature(fd, &sigh, l->signature_type, &msg);
01205 switch (rc) {
01206 default:
01207 rpmError(RPMERR_SIGGEN, _("%s: rpmReadSignature failed: %s"), fn,
01208 (msg && *msg ? msg : "\n"));
01209 msg = _free(msg);
01210 goto exit;
01211 break;
01212 case RPMRC_OK:
01213 if (sigh == NULL) {
01214 rpmError(RPMERR_SIGGEN, _("%s: No signature available\n"), fn);
01215 rc = RPMRC_FAIL;
01216 goto exit;
01217 }
01218 break;
01219 }
01220 msg = _free(msg);
01221
01222 #define _chk(_mask) (sigtag == 0 && !(vsflags & (_mask)))
01223
01224
01225
01226
01227
01228
01229
01230 sigtag = 0;
01231 opx = 0;
01232 vsflags = rpmtsVSFlags(ts);
01233 if (_chk(RPMVSF_NODSAHEADER) && headerIsEntry(sigh, RPMSIGTAG_DSA)) {
01234 sigtag = RPMSIGTAG_DSA;
01235 } else
01236 if (_chk(RPMVSF_NORSAHEADER) && headerIsEntry(sigh, RPMSIGTAG_RSA)) {
01237 sigtag = RPMSIGTAG_RSA;
01238 } else
01239 if (_chk(RPMVSF_NODSA|RPMVSF_NEEDPAYLOAD) &&
01240 headerIsEntry(sigh, RPMSIGTAG_GPG))
01241 {
01242 sigtag = RPMSIGTAG_GPG;
01243 fdInitDigest(fd, PGPHASHALGO_SHA1, 0);
01244 opx = RPMTS_OP_SIGNATURE;
01245 } else
01246 if (_chk(RPMVSF_NORSA|RPMVSF_NEEDPAYLOAD) &&
01247 headerIsEntry(sigh, RPMSIGTAG_PGP))
01248 {
01249 sigtag = RPMSIGTAG_PGP;
01250 fdInitDigest(fd, PGPHASHALGO_MD5, 0);
01251 opx = RPMTS_OP_SIGNATURE;
01252 } else
01253 if (_chk(RPMVSF_NOSHA1HEADER) && headerIsEntry(sigh, RPMSIGTAG_SHA1)) {
01254 sigtag = RPMSIGTAG_SHA1;
01255 } else
01256 if (_chk(RPMVSF_NOMD5|RPMVSF_NEEDPAYLOAD) &&
01257 headerIsEntry(sigh, RPMSIGTAG_MD5))
01258 {
01259 sigtag = RPMSIGTAG_MD5;
01260 fdInitDigest(fd, PGPHASHALGO_MD5, 0);
01261 opx = RPMTS_OP_DIGEST;
01262 }
01263
01264
01265 h = NULL;
01266 msg = NULL;
01267
01268
01269
01270 if (opx > 0)
01271 (void) rpmswEnter(rpmtsOp(ts, opx), 0);
01272
01273 nb = -fd->stats->ops[FDSTAT_READ].bytes;
01274 rc = rpmReadHeader(ts, fd, &h, &msg);
01275 nb += fd->stats->ops[FDSTAT_READ].bytes;
01276
01277 if (opx > 0)
01278 (void) rpmswExit(rpmtsOp(ts, opx), nb);
01279
01280 if (rc != RPMRC_OK || h == NULL) {
01281 rpmError(RPMERR_FREAD, _("%s: headerRead failed: %s"), fn,
01282 (msg && *msg ? msg : "\n"));
01283 msg = _free(msg);
01284 goto exit;
01285 }
01286 msg = _free(msg);
01287
01288
01289 if (sigtag == 0) {
01290 rc = RPMRC_OK;
01291 goto exit;
01292 }
01293
01294 dig = rpmtsDig(ts);
01295 if (dig == NULL) {
01296 rc = RPMRC_FAIL;
01297 goto exit;
01298 }
01299 dig->nbytes = 0;
01300
01301
01302 sig = NULL;
01303 xx = headerGetEntry(sigh, sigtag, &sigtype, (void **) &sig, &siglen);
01304 if (sig == NULL) {
01305 rc = RPMRC_FAIL;
01306 goto exit;
01307 }
01308 (void) rpmtsSetSig(ts, sigtag, sigtype, sig, siglen);
01309
01310 switch (sigtag) {
01311 case RPMSIGTAG_RSA:
01312
01313 xx = pgpPrtPkts(sig, siglen, dig, (_print_pkts & rpmIsDebug()));
01314 if (dig->signature.version != 3 && dig->signature.version != 4) {
01315 rpmMessage(RPMMESS_ERROR,
01316 _("skipping package %s with unverifiable V%u signature\n"),
01317 fn, dig->signature.version);
01318 rc = RPMRC_FAIL;
01319 goto exit;
01320 }
01321 { void * uh = NULL;
01322 int_32 uht;
01323 int_32 uhc;
01324
01325 if (!headerGetEntry(h, RPMTAG_HEADERIMMUTABLE, &uht, &uh, &uhc))
01326 break;
01327 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
01328 dig->hdrmd5ctx = rpmDigestInit(dig->signature.hash_algo, RPMDIGEST_NONE);
01329 (void) rpmDigestUpdate(dig->hdrmd5ctx, header_magic, sizeof(header_magic));
01330 dig->nbytes += sizeof(header_magic);
01331 (void) rpmDigestUpdate(dig->hdrmd5ctx, uh, uhc);
01332 dig->nbytes += uhc;
01333 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), dig->nbytes);
01334 rpmtsOp(ts, RPMTS_OP_DIGEST)->count--;
01335 uh = headerFreeData(uh, uht);
01336 } break;
01337 case RPMSIGTAG_DSA:
01338
01339 xx = pgpPrtPkts(sig, siglen, dig, (_print_pkts & rpmIsDebug()));
01340 if (dig->signature.version != 3 && dig->signature.version != 4) {
01341 rpmMessage(RPMMESS_ERROR,
01342 _("skipping package %s with unverifiable V%u signature\n"),
01343 fn, dig->signature.version);
01344 rc = RPMRC_FAIL;
01345 goto exit;
01346 }
01347
01348 case RPMSIGTAG_SHA1:
01349 { void * uh = NULL;
01350 int_32 uht;
01351 int_32 uhc;
01352
01353 if (!headerGetEntry(h, RPMTAG_HEADERIMMUTABLE, &uht, &uh, &uhc))
01354 break;
01355 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
01356 dig->hdrsha1ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
01357 (void) rpmDigestUpdate(dig->hdrsha1ctx, header_magic, sizeof(header_magic));
01358 dig->nbytes += sizeof(header_magic);
01359 (void) rpmDigestUpdate(dig->hdrsha1ctx, uh, uhc);
01360 dig->nbytes += uhc;
01361 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), dig->nbytes);
01362 if (sigtag == RPMSIGTAG_SHA1)
01363 rpmtsOp(ts, RPMTS_OP_DIGEST)->count--;
01364 uh = headerFreeData(uh, uht);
01365 } break;
01366 case RPMSIGTAG_GPG:
01367 case RPMSIGTAG_PGP5:
01368 case RPMSIGTAG_PGP:
01369
01370 xx = pgpPrtPkts(sig, siglen, dig, (_print_pkts & rpmIsDebug()));
01371
01372 if (dig->signature.version != 3 && dig->signature.version != 4) {
01373 rpmMessage(RPMMESS_ERROR,
01374 _("skipping package %s with unverifiable V%u signature\n"),
01375 fn, dig->signature.version);
01376 rc = RPMRC_FAIL;
01377 goto exit;
01378 }
01379
01380 case RPMSIGTAG_MD5:
01381
01382 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
01383 while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), fd)) > 0)
01384 dig->nbytes += count;
01385 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), dig->nbytes);
01386 rpmtsOp(ts, RPMTS_OP_DIGEST)->count--;
01387 dig->nbytes += nb;
01388 if (count < 0) {
01389 rpmError(RPMERR_FREAD, _("%s: Fread failed: %s\n"),
01390 fn, Fstrerror(fd));
01391 rc = RPMRC_FAIL;
01392 goto exit;
01393 }
01394
01395
01396 for (i = fd->ndigests - 1; i >= 0; i--) {
01397 FDDIGEST_t fddig = fd->digests + i;
01398 if (fddig->hashctx != NULL)
01399 switch (fddig->hashalgo) {
01400 case PGPHASHALGO_MD5:
01401 dig->md5ctx = fddig->hashctx;
01402 fddig->hashctx = NULL;
01403 break;
01404 case PGPHASHALGO_SHA1:
01405 case PGPHASHALGO_RIPEMD160:
01406 #if HAVE_BEECRYPT_API_H
01407 case PGPHASHALGO_SHA256:
01408 case PGPHASHALGO_SHA384:
01409 case PGPHASHALGO_SHA512:
01410 #endif
01411 dig->sha1ctx = fddig->hashctx;
01412 fddig->hashctx = NULL;
01413 break;
01414 default:
01415 break;
01416 }
01417 }
01418 break;
01419 }
01420
01423
01424 buf[0] = '\0';
01425
01426 rc = rpmVerifySignature(ts, buf);
01427 switch (rc) {
01428 case RPMRC_OK:
01429 rpmMessage(RPMMESS_DEBUG, "%s: %s", fn, buf);
01430 break;
01431 case RPMRC_NOTTRUSTED:
01432 case RPMRC_NOKEY:
01433
01434 { int lvl = (rpmtsStashKeyid(ts) ? RPMMESS_DEBUG : RPMMESS_WARNING);
01435 rpmMessage(lvl, "%s: %s", fn, buf);
01436 } break;
01437 case RPMRC_NOTFOUND:
01438 rpmMessage(RPMMESS_WARNING, "%s: %s", fn, buf);
01439 break;
01440 default:
01441 case RPMRC_FAIL:
01442 rpmMessage(RPMMESS_ERROR, "%s: %s", fn, buf);
01443 break;
01444 }
01445
01446 exit:
01447 if (rc != RPMRC_FAIL && h != NULL && hdrp != NULL) {
01448
01449
01450 headerMergeLegacySigs(h, sigh);
01451
01452 #if defined(RPM_VENDOR_MANDRIVA)
01453 rpm3to4(h);
01454 #endif
01455
01456 rpm3to4(h);
01457
01458
01459
01460 *hdrp = headerLink(h);
01461
01462 }
01463 h = headerFree(h);
01464
01465
01466 (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_READHDR),
01467 fdstat_op(fd, FDSTAT_READ));
01468 (void) rpmswSub(rpmtsOp(ts, RPMTS_OP_READHDR),
01469 opsave);
01470
01471 rpmtsCleanDig(ts);
01472 sigh = rpmFreeSignature(sigh);
01473 return rc;
01474 }
01475