00001
00006 #include "system.h"
00007
00008 #if defined(HAVE_MACHINE_TYPES_H)
00009 # include <machine/types.h>
00010 #endif
00011
00012 #include <netinet/in.h>
00013
00014 #define _RPMIOB_INTERNAL
00015 #include <rpmiotypes.h>
00016 #include <rpmio_internal.h>
00017 #include <rpmcb.h>
00018 #include <rpmbc.h>
00019 #include <rpmmacro.h>
00020 #include <rpmku.h>
00021
00022 #define _RPMTAG_INTERNAL
00023 #include "header_internal.h"
00024
00025 #include <rpmdb.h>
00026 #include <pkgio.h>
00027
00028 #define _RPMTS_INTERNAL
00029 #include "rpmts.h"
00030
00031 #include <rpmxar.h>
00032
00033 #include "signature.h"
00034 #include "debug.h"
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 int _pkgio_debug = 0;
00048
00049
00050 static int _print_pkts = 0;
00051
00054
00055 ssize_t timedRead(FD_t fd, void * bufptr, size_t length)
00056
00057 ;
00058 #define timedRead (ufdio->read)
00059
00060
00061
00069 static
00070 rpmRC rpmWriteHeader(FD_t fd, Header h, const char ** msg)
00071
00072
00073 {
00074 const void * uh = NULL;
00075 size_t nb;
00076 size_t length;
00077 rpmRC rc = RPMRC_FAIL;
00078
00079 if (_pkgio_debug)
00080 fprintf(stderr, "--> rpmWriteHeader(%p, %p, %p)\n", fd, h, msg);
00081
00082 if (h == NULL) {
00083 if (msg)
00084 *msg = xstrdup(_("write of NULL header"));
00085 goto exit;
00086 }
00087
00088 uh = headerUnload(h, &length);
00089 if (uh == NULL) {
00090 if (msg)
00091 *msg = xstrdup(_("headerUnload failed"));
00092 goto exit;
00093 }
00094
00095 { unsigned char * hmagic = NULL;
00096 size_t nmagic = 0;
00097
00098 (void) headerGetMagic(NULL, &hmagic, &nmagic);
00099 nb = Fwrite(hmagic, sizeof(hmagic[0]), nmagic, fd);
00100 if (nb != nmagic || Ferror(fd)) {
00101 if (msg)
00102 *msg = (nb > 0
00103 ? xstrdup(_("short write of header magic"))
00104 : xstrdup(Fstrerror(fd)) );
00105 goto exit;
00106 }
00107 }
00108
00109
00110 nb = Fwrite(uh, sizeof(char), length, fd);
00111
00112 if (nb != length || Ferror(fd)) {
00113 if (msg)
00114 *msg = (nb > 0
00115 ? xstrdup(_("short write of header"))
00116 : xstrdup(Fstrerror(fd)) );
00117 goto exit;
00118 }
00119 rc = RPMRC_OK;
00120
00121 exit:
00122 uh = _free(uh);
00123 return rc;
00124 }
00125
00126
00127
00128 rpmop rpmtsOp(rpmts ts, rpmtsOpX opx)
00129 {
00130 rpmop op = NULL;
00131
00132 if (ts != NULL && (int)opx >= 0 && (int)opx < RPMTS_OP_MAX)
00133 op = ts->ops + opx;
00134
00135 return op;
00136
00137 }
00138
00139 pgpDigParams rpmtsPubkey(const rpmts ts)
00140 {
00141
00142 return pgpGetPubkey(rpmtsDig(ts));
00143
00144 }
00145
00146 rpmdb rpmtsGetRdb(rpmts ts)
00147 {
00148 rpmdb rdb = NULL;
00149 if (ts != NULL) {
00150 rdb = ts->rdb;
00151 }
00152
00153 return rdb;
00154
00155 }
00156
00157 rpmRC rpmtsFindPubkey(rpmts ts, void * _dig)
00158 {
00159 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
00160 pgpDig dig = (_dig ? _dig : rpmtsDig(ts));
00161 pgpDigParams sigp = pgpGetSignature(dig);
00162 pgpDigParams pubp = pgpGetPubkey(dig);
00163 rpmRC res = RPMRC_NOKEY;
00164 const char * pubkeysource = NULL;
00165 rpmiob iob = NULL;
00166 int krcache = 1;
00167 int xx;
00168
00169 assert(dig != NULL);
00170 assert(sigp != NULL);
00171 assert(pubp != NULL);
00172
00173 assert(rpmtsDig(ts) == dig);
00174
00175
00176 #if 0
00177 fprintf(stderr, "==> find sig id %08x %08x ts pubkey id %08x %08x\n",
00178 pgpGrab(sigp->signid, 4), pgpGrab(sigp->signid+4, 4),
00179 pgpGrab(ts->pksignid, 4), pgpGrab(ts->pksignid+4, 4));
00180 #endif
00181
00182
00183 if (memcmp(sigp->signid, ts->pksignid, sizeof(ts->pksignid))) {
00184 #if 0
00185 fprintf(stderr, "*** free pkt %p[%d] id %08x %08x\n", ts->pkpkt, ts->pkpktlen, pgpGrab(ts->pksignid, 4), pgpGrab(ts->pksignid+4, 4));
00186 #endif
00187 ts->pkpkt = _free(ts->pkpkt);
00188 ts->pkpktlen = 0;
00189 memset(ts->pksignid, 0, sizeof(ts->pksignid));
00190 }
00191
00192
00193 if (ts->pkpkt == NULL) {
00194 iob = NULL;
00195 switch (rpmkuFindPubkey(sigp, &iob)) {
00196 case RPMRC_NOTFOUND:
00197 case RPMRC_FAIL:
00198 case RPMRC_NOTTRUSTED:
00199 case RPMRC_NOKEY:
00200 break;
00201 case RPMRC_OK:
00202 pubkeysource = xstrdup("keyutils");
00203 krcache = 0;
00204 ts->pkpkt = memcpy(xmalloc(iob->blen), iob->b, iob->blen);
00205 ts->pkpktlen = iob->blen;
00206 break;
00207 }
00208 }
00209
00210
00211 if (ts->pkpkt == NULL) {
00212 unsigned hx = 0xffffffff;
00213 unsigned ix = 0xffffffff;
00214 rpmmi mi;
00215 Header h;
00216
00217
00218 if (ts->rdb == NULL) {
00219 xx = rpmdbOpen(ts->rootDir, &ts->rdb, ts->dbmode, 0644);
00220 if (xx) {
00221 const char * dn = rpmGetPath(ts->rootDir, "%{_dbpath}", NULL);
00222 rpmlog(RPMLOG_ERR,
00223 _("cannot open Packages database in %s\n"), dn);
00224 dn = _free(dn);
00225 }
00226 }
00227
00228
00229 he->tag = RPMTAG_PUBKEYS;
00230
00231 mi = rpmmiInit(rpmtsGetRdb(ts), RPMTAG_PUBKEYS, sigp->signid, sizeof(sigp->signid));
00232
00233 while ((h = rpmmiNext(mi)) != NULL) {
00234 if (!headerGet(h, he, 0))
00235 continue;
00236 hx = rpmmiInstance(mi);
00237 ix = rpmmiFilenum(mi);
00238
00239 if (ix >= (unsigned) he->c
00240 || b64decode(he->p.argv[ix], (void **) &ts->pkpkt, &ts->pkpktlen))
00241 ix = 0xffffffff;
00242
00243 he->p.ptr = _free(he->p.ptr);
00244 break;
00245 }
00246 mi = rpmmiFree(mi);
00247
00248 if (ix < 0xffffffff) {
00249 char hnum[32];
00250 sprintf(hnum, "h#%u", hx);
00251 pubkeysource = xstrdup(hnum);
00252 } else {
00253 ts->pkpkt = _free(ts->pkpkt);
00254 ts->pkpktlen = 0;
00255 }
00256 }
00257
00258
00259 if (ts->pkpkt == NULL) {
00260 const char * fn = rpmExpand("%{_hkp_keyserver_query}",
00261 pgpHexStr(sigp->signid, sizeof(sigp->signid)), NULL);
00262
00263 xx = 0;
00264 if (fn && *fn != '%') {
00265 xx = (pgpReadPkts(fn, &ts->pkpkt, &ts->pkpktlen) != PGPARMOR_PUBKEY);
00266 }
00267 fn = _free(fn);
00268 if (xx) {
00269 ts->pkpkt = _free(ts->pkpkt);
00270 ts->pkpktlen = 0;
00271 } else {
00272
00273 pubkeysource = xstrdup("keyserver");
00274 }
00275 }
00276
00277 #ifdef NOTNOW
00278
00279 if (ts->pkpkt == NULL) {
00280 const char * fn = rpmExpand("%{_gpg_pubkey}", NULL);
00281
00282 xx = 0;
00283 if (fn && *fn != '%')
00284 xx = (pgpReadPkts(fn,&ts->pkpkt,&ts->pkpktlen) != PGPARMOR_PUBKEY);
00285 fn = _free(fn);
00286 if (xx) {
00287 ts->pkpkt = _free(ts->pkpkt);
00288 ts->pkpktlen = 0;
00289 } else {
00290 pubkeysource = xstrdup("macro");
00291 }
00292 }
00293 #endif
00294
00295
00296 if (ts->pkpkt == NULL || ts->pkpktlen == 0)
00297 goto exit;
00298
00299
00300 xx = pgpPrtPkts((rpmuint8_t *)ts->pkpkt, ts->pkpktlen, dig, 0);
00301
00302
00303 if (sigp->pubkey_algo == pubp->pubkey_algo
00304 #ifdef NOTYET
00305 && sigp->hash_algo == pubp->hash_algo
00306 #endif
00307 && !memcmp(sigp->signid, pubp->signid, sizeof(sigp->signid)) )
00308 {
00309
00310
00311
00312
00313 if (krcache) {
00314 if (iob == NULL) {
00315 iob = rpmiobNew(ts->pkpktlen);
00316 iob->b = memcpy(iob->b, ts->pkpkt, iob->blen);
00317 }
00318 (void) rpmkuStorePubkey(sigp, iob);
00319 }
00320
00321
00322 memcpy(ts->pksignid, pubp->signid, sizeof(ts->pksignid));
00323
00324 if (pubkeysource)
00325 rpmlog(RPMLOG_DEBUG, "========== %s pubkey id %08x %08x (%s)\n",
00326 (sigp->pubkey_algo == (rpmuint8_t)PGPPUBKEYALGO_DSA ? "DSA" :
00327 (sigp->pubkey_algo == (rpmuint8_t)PGPPUBKEYALGO_RSA ? "RSA" :
00328 "???")),
00329 pgpGrab(sigp->signid, 4), pgpGrab(sigp->signid+4, 4),
00330 pubkeysource);
00331
00332 res = RPMRC_OK;
00333 }
00334
00335 exit:
00336 pubkeysource = _free(pubkeysource);
00337 if (res != RPMRC_OK) {
00338 ts->pkpkt = _free(ts->pkpkt);
00339 ts->pkpktlen = 0;
00340 }
00341
00342 return res;
00343
00344 }
00345
00346 pgpDig rpmtsDig(rpmts ts)
00347 {
00348
00349 if (ts->dig == NULL) {
00350 ts->dig = pgpDigNew(0);
00351
00352 (void) pgpSetFindPubkey(ts->dig, (int (*)(void *, void *))rpmtsFindPubkey, ts);
00353
00354 }
00355
00356
00357 return ts->dig;
00358
00359 }
00360
00361 void rpmtsCleanDig(rpmts ts)
00362 {
00363 if (ts && ts->dig) {
00364 int opx;
00365 opx = RPMTS_OP_DIGEST;
00366 (void) rpmswAdd(rpmtsOp(ts, opx), pgpStatsAccumulator(ts->dig, opx));
00367 opx = RPMTS_OP_SIGNATURE;
00368 (void) rpmswAdd(rpmtsOp(ts, opx), pgpStatsAccumulator(ts->dig, opx));
00369
00370 (void) pgpDigFree(ts->dig, "rpmtsCleanDig");
00371 ts->dig = NULL;
00372
00373 }
00374 }
00375
00376
00377
00384 struct rpmlead {
00385 unsigned char magic[4];
00386 unsigned char major;
00387 unsigned char minor;
00388 unsigned short type;
00389 unsigned short archnum;
00390 char name[66];
00391 unsigned short osnum;
00392 unsigned short signature_type;
00393
00394 char reserved[16];
00395 } ;
00396
00397
00398
00399 static unsigned char lead_magic[] = {
00400 0xed, 0xab, 0xee, 0xdb, 0x00, 0x00, 0x00, 0x00
00401 };
00402
00403
00404
00405
00413 static rpmRC wrLead(FD_t fd, const void * ptr, const char ** msg)
00414
00415
00416 {
00417 struct rpmlead l;
00418
00419 if (_pkgio_debug)
00420 fprintf(stderr, "--> wrLead(%p, %p, %p)\n", fd, ptr, msg);
00421
00422 memcpy(&l, ptr, sizeof(l));
00423
00424
00425 if ((int)l.major == 0)
00426 l.major = (unsigned char) 3;
00427 if (l.signature_type == 0)
00428 l.signature_type = 5;
00429 if (msg && *msg)
00430 (void) strncpy(l.name, *msg, sizeof(l.name));
00431
00432 memcpy(&l.magic, lead_magic, sizeof(l.magic));
00433 l.type = (unsigned short) htons(l.type);
00434 l.archnum = (unsigned short) htons(l.archnum);
00435 l.osnum = (unsigned short) htons(l.osnum);
00436 l.signature_type = (unsigned short) htons(l.signature_type);
00437
00438 if (Fwrite(&l, 1, sizeof(l), fd) != sizeof(l))
00439 return RPMRC_FAIL;
00440
00441 return RPMRC_OK;
00442 }
00443
00451 static rpmRC rdLead(FD_t fd, void * ptr,
00452 const char ** msg)
00453
00454
00455 {
00456 rpmxar xar = fdGetXAR(fd);
00457 struct rpmlead ** leadp = ptr;
00458 struct rpmlead * l = xcalloc(1, sizeof(*l));
00459 char buf[BUFSIZ];
00460 rpmRC rc = RPMRC_FAIL;
00461 int xx;
00462
00463 if (_pkgio_debug)
00464 fprintf(stderr, "--> rdLead(%p, %p, %p)\n", fd, ptr, msg);
00465
00466 buf[0] = '\0';
00467 if (leadp != NULL) *leadp = NULL;
00468
00469
00470 if ((xx = (int) timedRead(fd, (char *)l, sizeof(*l))) != (int) sizeof(*l)) {
00471 if (Ferror(fd)) {
00472 (void) snprintf(buf, sizeof(buf),
00473 _("lead size(%u): BAD, read(%d), %s(%d)"),
00474 (unsigned)sizeof(*l), xx, Fstrerror(fd), errno);
00475 rc = RPMRC_FAIL;
00476 } else {
00477 (void) snprintf(buf, sizeof(buf),
00478 _("lead size(%u): BAD, read(%d), %s(%d)"),
00479 (unsigned)sizeof(*l), xx, strerror(errno), errno);
00480 rc = RPMRC_NOTFOUND;
00481 }
00482 goto exit;
00483 }
00484
00485
00486 if (xar == NULL) {
00487 unsigned char * bh = (unsigned char *)l;
00488 if (bh[0] == 'x' && bh[1] == 'a' && bh[2] == 'r' && bh[3] == '!') {
00489 const char * fn = fdGetOPath(fd);
00490 assert(fn != NULL);
00491 xar = rpmxarNew(fn, "r");
00492 fdSetXAR(fd, xar);
00493 (void) rpmxarFree(xar, "rdLead");
00494 }
00495 }
00496
00497
00498 xar = fdGetXAR(fd);
00499 if (xar != NULL) {
00500 unsigned char *b = NULL;
00501 size_t nb = 0;
00502 const char item[] = "Lead";
00503 if ((xx = rpmxarNext(xar)) != 0 || (xx = rpmxarPull(xar, item)) != 0) {
00504 (void) snprintf(buf, sizeof(buf),
00505 _("XAR file not found (or no XAR support)"));
00506 rc = RPMRC_NOTFOUND;
00507 goto exit;
00508 }
00509 (void) rpmxarSwapBuf(xar, NULL, 0, &b, &nb);
00510 if (nb != sizeof(*l)) {
00511 (void) snprintf(buf, sizeof(buf),
00512 _("lead size(%u): BAD, xar read(%u)"),
00513 (unsigned)sizeof(*l), (unsigned)nb);
00514 b = _free(b);
00515 rc = RPMRC_FAIL;
00516 goto exit;
00517 }
00518 memcpy(l, b, nb);
00519 b = _free(b);
00520 }
00521
00522 l->type = (unsigned short) ntohs(l->type);
00523 l->archnum = (unsigned short) ntohs(l->archnum);
00524 l->osnum = (unsigned short) ntohs(l->osnum);
00525 l->signature_type = (unsigned short) ntohs(l->signature_type);
00526
00527 if (memcmp(l->magic, lead_magic, sizeof(l->magic))) {
00528
00529 (void) snprintf(buf, sizeof(buf), _("lead magic: BAD, read %02x%02x%02x%02x"), l->magic[0], l->magic[1], l->magic[2], l->magic[3]);
00530
00531 rc = RPMRC_NOTFOUND;
00532 goto exit;
00533 }
00534
00535 switch (l->major) {
00536 default:
00537 (void) snprintf(buf, sizeof(buf),
00538 _("lead version(%u): UNSUPPORTED"), (unsigned) l->major);
00539 rc = RPMRC_NOTFOUND;
00540 goto exit;
00541 break;
00542 case 3:
00543 case 4:
00544 break;
00545 }
00546
00547 if (l->signature_type != 5) {
00548 (void) snprintf(buf, sizeof(buf),
00549 _("sigh type(%u): UNSUPPORTED"), (unsigned) l->signature_type);
00550 rc = RPMRC_NOTFOUND;
00551 goto exit;
00552 }
00553
00554 rc = RPMRC_OK;
00555
00556 exit:
00557 if (rc == RPMRC_OK && leadp != NULL)
00558 *leadp = l;
00559 else
00560 l = _free(l);
00561
00562 if (msg != NULL && buf[0] != '\0') {
00563 buf[sizeof(buf)-1] = '\0';
00564 *msg = xstrdup(buf);
00565 }
00566 return rc;
00567 }
00568
00569
00570
00578 static rpmRC wrSignature(FD_t fd, void * ptr,
00579 const char ** msg)
00580
00581
00582 {
00583 Header sigh = ptr;
00584 static unsigned char zero[8]
00585 = { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' };
00586 size_t sigSize;
00587 size_t pad;
00588 rpmRC rc = RPMRC_OK;
00589
00590 if (_pkgio_debug)
00591 fprintf(stderr, "--> wrSignature(%p, %p, %p)\n", fd, ptr, msg);
00592
00593 rc = rpmWriteHeader(fd, sigh, msg);
00594 if (rc != RPMRC_OK)
00595 return rc;
00596
00597 sigSize = headerSizeof(sigh);
00598 pad = (8 - (sigSize % 8)) % 8;
00599 if (pad) {
00600 if (Fwrite(zero, sizeof(zero[0]), pad, fd) != pad)
00601 rc = RPMRC_FAIL;
00602 }
00603 rpmlog(RPMLOG_DEBUG, D_("Signature: size(%u)+pad(%u)\n"), (unsigned)sigSize, (unsigned)pad);
00604 return rc;
00605 }
00606
00615 static inline rpmRC printSize(FD_t fd, size_t siglen, size_t pad, size_t datalen)
00616
00617
00618 {
00619 struct stat sb, * st = &sb;
00620 size_t expected;
00621 size_t nl = rpmpkgSizeof("Lead", NULL);
00622
00623 #ifndef DYING
00624 int fdno = Fileno(fd);
00625
00626 if (fdno == 123456789) {
00627
00628 st->st_size = 0;
00629 st->st_size -= nl + siglen + pad + datalen;
00630
00631 } else
00632 #endif
00633 if (Fstat(fd, st) < 0)
00634 return RPMRC_FAIL;
00635
00636 expected = nl + siglen + pad + datalen;
00637 rpmlog(RPMLOG_DEBUG,
00638 D_("Expected size: %12lu = lead(%u)+sigs(%u)+pad(%u)+data(%lu)\n"),
00639 (unsigned long)expected,
00640 (unsigned)nl, (unsigned) siglen, (unsigned) pad,
00641 (unsigned long)datalen);
00642 rpmlog(RPMLOG_DEBUG,
00643 D_(" Actual size: %12lu\n"), (unsigned long)st->st_size);
00644
00645 return RPMRC_OK;
00646 }
00647
00655 static rpmRC rdSignature(FD_t fd, void * ptr,
00656 const char ** msg)
00657
00658
00659 {
00660 rpmxar xar = fdGetXAR(fd);
00661 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
00662 Header * sighp = ptr;
00663 char buf[BUFSIZ];
00664 rpmuint32_t block[4];
00665 rpmuint32_t il;
00666 rpmuint32_t dl;
00667 rpmuint32_t * ei = NULL;
00668 entryInfo pe;
00669 size_t startoff;
00670 size_t nb;
00671 rpmuint32_t ril = 0;
00672 indexEntry entry = memset(alloca(sizeof(*entry)), 0, sizeof(*entry));
00673 entryInfo info = memset(alloca(sizeof(*info)), 0, sizeof(*info));
00674 unsigned char * dataStart;
00675 unsigned char * dataEnd = NULL;
00676 Header sigh = NULL;
00677 rpmRC rc = RPMRC_FAIL;
00678 int xx;
00679 rpmuint32_t i;
00680 static int map = 1;
00681
00682 if (_pkgio_debug)
00683 fprintf(stderr, "--> rdSignature(%p, %p, %p)\n", fd, ptr, msg);
00684
00685 buf[0] = '\0';
00686 if (sighp)
00687 *sighp = NULL;
00688
00689 memset(block, 0, sizeof(block));
00690 if (xar != NULL) {
00691 const char item[] = "Signature";
00692 if ((xx = rpmxarNext(xar)) != 0 || (xx = rpmxarPull(xar, item)) != 0) {
00693 (void) snprintf(buf, sizeof(buf),
00694 _("XAR file not found (or no XAR support)"));
00695 rc = RPMRC_NOTFOUND;
00696 goto exit;
00697 }
00698 }
00699 startoff = fd->stats->ops[FDSTAT_READ].bytes;
00700 if ((xx = (int) timedRead(fd, (void *)block, sizeof(block))) != (int) sizeof(block)) {
00701 (void) snprintf(buf, sizeof(buf),
00702 _("sigh size(%d): BAD, read returned %d"), (int)sizeof(block), xx);
00703 goto exit;
00704 }
00705
00706 { unsigned char * hmagic = NULL;
00707 size_t nmagic = 0;
00708
00709 (void) headerGetMagic(NULL, &hmagic, &nmagic);
00710
00711 if (memcmp(block, hmagic, nmagic)) {
00712 unsigned char * x = (unsigned char *)block;
00713
00714 (void) snprintf(buf, sizeof(buf), _("sigh magic: BAD, read %02x%02x%02x%02x%02x%02x%02x%02x"), x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7]);
00715
00716 goto exit;
00717 }
00718 }
00719 il = (rpmuint32_t) ntohl(block[2]);
00720 if (il > 32) {
00721 (void) snprintf(buf, sizeof(buf),
00722 _("sigh tags: BAD, no. of tags(%u) out of range"), (unsigned) il);
00723 goto exit;
00724 }
00725 dl = (rpmuint32_t) ntohl(block[3]);
00726 if (dl > 8192) {
00727 (void) snprintf(buf, sizeof(buf),
00728 _("sigh data: BAD, no. of bytes(%u) out of range"), (unsigned) dl);
00729 goto exit;
00730 }
00731
00732
00733 nb = (il * sizeof(struct entryInfo_s)) + dl;
00734
00735 if (map) {
00736 size_t pvlen = (sizeof(il) + sizeof(dl) + nb);
00737 static const int prot = PROT_READ | PROT_WRITE;
00738 static const int flags = MAP_PRIVATE| MAP_ANONYMOUS;
00739 static const int fdno = -1;
00740 static const off_t off = 0;
00741
00742 ei = mmap(NULL, pvlen, prot, flags, fdno, off);
00743 if (ei == NULL || ei == (void *)-1)
00744 fprintf(stderr,
00745 "==> mmap(%p[%u], 0x%x, 0x%x, %d, 0x%x) error(%d): %s\n",
00746 NULL, pvlen, prot, flags, fdno, (unsigned)off,
00747 errno, strerror(errno));
00748 } else {
00749 size_t pvlen = (sizeof(il) + sizeof(dl) + nb);
00750 ei = xmalloc(pvlen);
00751 }
00752
00753 if ((xx = (int) timedRead(fd, (void *)&ei[2], nb)) != (int) nb) {
00754 (void) snprintf(buf, sizeof(buf),
00755 _("sigh blob(%u): BAD, read returned %d"), (unsigned) nb, xx);
00756 goto exit;
00757 }
00758 ei[0] = block[2];
00759 ei[1] = block[3];
00760
00761 if (map) {
00762 size_t pvlen = (sizeof(il) + sizeof(dl) + nb);
00763 if (mprotect(ei, pvlen, PROT_READ) != 0)
00764 fprintf(stderr, "==> mprotect(%p[%u],0x%x) error(%d): %s\n",
00765 ei, pvlen, PROT_READ,
00766 errno, strerror(errno));
00767 }
00768
00769 pe = (entryInfo) &ei[2];
00770 dataStart = (unsigned char *) (pe + il);
00771
00772
00773 xx = headerVerifyInfo(1, dl, pe, &entry->info, 0);
00774 if (xx != -1) {
00775 (void) snprintf(buf, sizeof(buf),
00776 _("tag[%d]: BAD, tag %u type %u offset %d count %u"),
00777 0, (unsigned) entry->info.tag, (unsigned) entry->info.type,
00778 (int)entry->info.offset, (unsigned) entry->info.count);
00779 goto exit;
00780 }
00781
00782
00783
00784 if (entry->info.tag == RPMTAG_HEADERSIGNATURES
00785 && entry->info.type == RPM_BIN_TYPE
00786 && entry->info.count == (rpmTagCount)REGION_TAG_COUNT)
00787 {
00788
00789
00790
00791
00792
00793
00794 assert(entry->info.offset >= 0);
00795 if (entry->info.offset >= (rpmint32_t)dl) {
00796 (void) snprintf(buf, sizeof(buf),
00797 _("region offset: BAD, tag %u type %u offset %d count %u"),
00798 (unsigned) entry->info.tag, (unsigned) entry->info.type,
00799 (int)entry->info.offset, (unsigned) entry->info.count);
00800 goto exit;
00801 }
00802
00803
00804 dataEnd = dataStart + entry->info.offset;
00805
00806 (void) memcpy(info, dataEnd, REGION_TAG_COUNT);
00807
00808 if (info->tag == (rpmuint32_t) htonl(RPMTAG_HEADERIMAGE)) {
00809 rpmuint32_t stag = (rpmuint32_t) htonl(RPMTAG_HEADERSIGNATURES);
00810 info->tag = stag;
00811 memcpy(dataEnd, &stag, sizeof(stag));
00812 }
00813 dataEnd += REGION_TAG_COUNT;
00814
00815 xx = headerVerifyInfo(1, dl, info, &entry->info, 1);
00816 if (xx != -1 ||
00817 !(entry->info.tag == RPMTAG_HEADERSIGNATURES
00818 && entry->info.type == RPM_BIN_TYPE
00819 && entry->info.count == (rpmTagCount)REGION_TAG_COUNT))
00820 {
00821 (void) snprintf(buf, sizeof(buf),
00822 _("region trailer: BAD, tag %u type %u offset %d count %u"),
00823 (unsigned) entry->info.tag, (unsigned) entry->info.type,
00824 (int)entry->info.offset, (unsigned) entry->info.count);
00825 goto exit;
00826 }
00827
00828 memset(info, 0, sizeof(*info));
00829
00830
00831 ril = (rpmuint32_t) (entry->info.offset/sizeof(*pe));
00832 if ((entry->info.offset % sizeof(*pe)) || ril > il) {
00833 (void) snprintf(buf, sizeof(buf),
00834 _("region size: BAD, ril(%u) > il(%u)"), (unsigned) ril, (unsigned) il);
00835 goto exit;
00836 }
00837 }
00838
00839
00840 memset(info, 0, sizeof(*info));
00841 for (i = 1; i < (unsigned) il; i++) {
00842 xx = headerVerifyInfo(1, dl, pe+i, &entry->info, 0);
00843 if (xx != -1) {
00844 (void) snprintf(buf, sizeof(buf),
00845 _("sigh tag[%u]: BAD, tag %u type %u offset %d count %u"),
00846 (unsigned) i, (unsigned) entry->info.tag, (unsigned) entry->info.type,
00847 (int)entry->info.offset, (unsigned) entry->info.count);
00848 goto exit;
00849 }
00850 }
00851
00852
00853 sigh = headerLoad(ei);
00854 if (sigh == NULL) {
00855 (void) snprintf(buf, sizeof(buf), _("sigh load: BAD"));
00856 goto exit;
00857 }
00858 if (map) {
00859 sigh->flags |= HEADERFLAG_MAPPED;
00860 sigh->flags |= HEADERFLAG_RDONLY;
00861 } else
00862 sigh->flags |= HEADERFLAG_ALLOCATED;
00863 sigh->flags |= HEADERFLAG_SIGNATURE;
00864
00865 { size_t sigSize = headerSizeof(sigh);
00866 size_t pad = (8 - (sigSize % 8)) % 8;
00867
00868
00869 if (pad && (xx = (int) timedRead(fd, (void *)block, pad)) != (int) pad)
00870 {
00871 (void) snprintf(buf, sizeof(buf),
00872 _("sigh pad(%u): BAD, read %d bytes"), (unsigned) pad, xx);
00873 goto exit;
00874 }
00875
00876
00877
00878 he->tag = (rpmTag) RPMSIGTAG_SIZE;
00879 xx = headerGet(sigh, he, 0);
00880 if (xx) {
00881 size_t datasize = he->p.ui32p[0];
00882 rc = printSize(fd, sigSize, pad, datasize);
00883 if (rc != RPMRC_OK)
00884 (void) snprintf(buf, sizeof(buf),
00885 _("sigh sigSize(%u): BAD, Fstat(2) failed"), (unsigned) sigSize);
00886 }
00887 he->p.ptr = _free(he->p.ptr);
00888 }
00889 (void) headerSetStartOff(sigh, (rpmuint32_t)startoff);
00890 (void) headerSetEndOff(sigh, fd->stats->ops[FDSTAT_READ].bytes);
00891
00892 exit:
00893 if (sighp && sigh && rc == RPMRC_OK)
00894 *sighp = headerLink(sigh);
00895 (void)headerFree(sigh);
00896 sigh = NULL;
00897
00898 if (msg != NULL) {
00899 buf[sizeof(buf)-1] = '\0';
00900 *msg = xstrdup(buf);
00901 }
00902
00903 return rc;
00904 }
00905
00906
00907
00921 rpmRC headerCheck(pgpDig dig, const void * uh, size_t uc, const char ** msg)
00922 {
00923 char buf[8*BUFSIZ];
00924 rpmuint32_t * ei = (rpmuint32_t *) uh;
00925 rpmuint32_t il = (rpmuint32_t) ntohl(ei[0]);
00926 rpmuint32_t dl = (rpmuint32_t) ntohl(ei[1]);
00927
00928 entryInfo pe = (entryInfo) &ei[2];
00929
00930 rpmuint32_t ildl[2];
00931 size_t pvlen = sizeof(ildl) + (il * sizeof(*pe)) + dl;
00932 unsigned char * dataStart = (unsigned char *) (pe + il);
00933 indexEntry entry = memset(alloca(sizeof(*entry)), 0, sizeof(*entry));
00934 entryInfo info = memset(alloca(sizeof(*info)), 0, sizeof(*info));
00935 const void * sig = NULL;
00936 unsigned char * b;
00937 rpmVSFlags vsflags = pgpDigVSFlags;
00938 rpmop op;
00939 size_t siglen = 0;
00940 int blen;
00941 size_t nb;
00942 rpmuint32_t ril = 0;
00943 unsigned char * regionEnd = NULL;
00944 rpmRC rc = RPMRC_FAIL;
00945 int xx;
00946 rpmuint32_t i;
00947
00948 if (_pkgio_debug)
00949 fprintf(stderr, "--> headerCheck(%p, %p[%u], %p)\n", dig, uh, (unsigned) uc, msg);
00950
00951 buf[0] = '\0';
00952
00953
00954 if (uc > 0 && pvlen != uc) {
00955 (void) snprintf(buf, sizeof(buf),
00956 _("blob size(%d): BAD, 8 + 16 * il(%u) + dl(%u)"),
00957 (int)uc, (unsigned)il, (unsigned)dl);
00958 goto exit;
00959 }
00960
00961
00962 xx = headerVerifyInfo(1, dl, pe, &entry->info, 0);
00963 if (xx != -1) {
00964 (void) snprintf(buf, sizeof(buf),
00965 _("tag[%d]: BAD, tag %u type %u offset %d count %u"),
00966 0, (unsigned) entry->info.tag, (unsigned) entry->info.type,
00967 (int)entry->info.offset, (unsigned) entry->info.count);
00968 goto exit;
00969 }
00970
00971
00972
00973 if (!(entry->info.tag == RPMTAG_HEADERIMMUTABLE
00974 && entry->info.type == RPM_BIN_TYPE
00975 && entry->info.count == (rpmTagCount)REGION_TAG_COUNT))
00976 {
00977 rc = RPMRC_NOTFOUND;
00978 goto exit;
00979 }
00980
00981
00982
00983 if (entry->info.offset >= (int) dl) {
00984 (void) snprintf(buf, sizeof(buf),
00985 _("region offset: BAD, tag %u type %u offset %d count %u"),
00986 (unsigned) entry->info.tag, (unsigned) entry->info.type,
00987 (int)entry->info.offset, (unsigned) entry->info.count);
00988 goto exit;
00989 }
00990
00991
00992 regionEnd = dataStart + entry->info.offset;
00993
00994 (void) memcpy(info, regionEnd, REGION_TAG_COUNT);
00995 regionEnd += REGION_TAG_COUNT;
00996
00997 xx = headerVerifyInfo(1, dl, info, &entry->info, 1);
00998 if (xx != -1 ||
00999 !(entry->info.tag == RPMTAG_HEADERIMMUTABLE
01000 && entry->info.type == RPM_BIN_TYPE
01001 && entry->info.count == (rpmTagCount)REGION_TAG_COUNT))
01002 {
01003 (void) snprintf(buf, sizeof(buf),
01004 _("region trailer: BAD, tag %u type %u offset %d count %u"),
01005 (unsigned) entry->info.tag, (unsigned) entry->info.type,
01006 (int)entry->info.offset, (unsigned) entry->info.count);
01007 goto exit;
01008 }
01009
01010 memset(info, 0, sizeof(*info));
01011
01012
01013 ril = (rpmuint32_t) (entry->info.offset/sizeof(*pe));
01014 if ((entry->info.offset % sizeof(*pe)) || ril > il) {
01015 (void) snprintf(buf, sizeof(buf),
01016 _("region size: BAD, ril(%u) > il(%u)"), (unsigned) ril, (unsigned)il);
01017 goto exit;
01018 }
01019
01020
01021 for (i = ril; i < (unsigned) il; i++) {
01022 xx = headerVerifyInfo(1, dl, pe+i, &entry->info, 0);
01023 if (xx != -1) {
01024 (void) snprintf(buf, sizeof(buf),
01025 _("tag[%u]: BAD, tag %u type %u offset %d count %u"),
01026 (unsigned) i, (unsigned) entry->info.tag, (unsigned) entry->info.type,
01027 (int)entry->info.offset, (unsigned) entry->info.count);
01028 goto exit;
01029 }
01030
01031 switch (entry->info.tag) {
01032 case RPMTAG_SHA1HEADER:
01033 if (vsflags & RPMVSF_NOSHA1HEADER)
01034 break;
01035 blen = 0;
01036 for (b = dataStart + entry->info.offset; *b != '\0'; b++) {
01037 if (strchr("0123456789abcdefABCDEF", *b) == NULL)
01038 break;
01039 blen++;
01040 }
01041 if (entry->info.type != RPM_STRING_TYPE || *b != '\0' || blen != 40)
01042 {
01043 (void) snprintf(buf, sizeof(buf), _("hdr SHA1: BAD, not hex"));
01044 goto exit;
01045 }
01046 if (info->tag == 0) {
01047 *info = entry->info;
01048 siglen = blen + 1;
01049 }
01050 break;
01051 case RPMTAG_RSAHEADER:
01052 if (vsflags & RPMVSF_NORSAHEADER)
01053 break;
01054 if (entry->info.type != RPM_BIN_TYPE) {
01055 (void) snprintf(buf, sizeof(buf), _("hdr RSA: BAD, not binary"));
01056 goto exit;
01057 }
01058 *info = entry->info;
01059 siglen = info->count;
01060 break;
01061 case RPMTAG_DSAHEADER:
01062 if (vsflags & RPMVSF_NODSAHEADER)
01063 break;
01064 if (entry->info.type != RPM_BIN_TYPE) {
01065 (void) snprintf(buf, sizeof(buf), _("hdr DSA: BAD, not binary"));
01066 goto exit;
01067 }
01068 *info = entry->info;
01069 siglen = info->count;
01070 break;
01071 default:
01072 break;
01073 }
01074 }
01075 rc = RPMRC_NOTFOUND;
01076
01077 exit:
01078
01079 if (rc != RPMRC_NOTFOUND) {
01080 buf[sizeof(buf)-1] = '\0';
01081 if (msg) *msg = xstrdup(buf);
01082 if (_pkgio_debug)
01083 fprintf(stderr, "--> headerCheck #1: rc %d \"%s\"\n", rc, (msg ? *msg: ""));
01084 return rc;
01085 }
01086
01087
01088 if (info->tag == 0) {
01089 xx = (ril > 0 ? headerVerifyInfo(ril-1, dl, pe+1, &entry->info, 0) : -1);
01090 if (xx != -1) {
01091 (void) snprintf(buf, sizeof(buf),
01092 _("tag[%d]: BAD, tag %u type %u offset %d count %u"),
01093 xx+1, (unsigned) entry->info.tag, (unsigned) entry->info.type,
01094 (int)entry->info.offset, (unsigned) entry->info.count);
01095 rc = RPMRC_FAIL;
01096 } else {
01097 (void) snprintf(buf, sizeof(buf), "Header sanity check: OK");
01098 rc = RPMRC_OK;
01099 }
01100 buf[sizeof(buf)-1] = '\0';
01101 if (msg) *msg = xstrdup(buf);
01102 if (_pkgio_debug)
01103 fprintf(stderr, "--> headerCheck #2: rc %d \"%s\"\n", rc, (msg ? *msg: ""));
01104 return rc;
01105 }
01106
01107
01108 assert(dig != NULL);
01109 dig->nbytes = 0;
01110
01111 sig = memcpy(xmalloc(siglen), dataStart + info->offset, siglen);
01112 {
01113 const void * osig = pgpGetSig(dig);
01114
01115 osig = _free(osig);
01116
01117 (void) pgpSetSig(dig, info->tag, info->type, sig, info->count);
01118 }
01119
01120 switch (info->tag) {
01121 case RPMTAG_RSAHEADER:
01122
01123 xx = pgpPrtPkts(sig, info->count, dig, (_print_pkts & rpmIsDebug()));
01124 if (dig->signature.version != (rpmuint8_t)3
01125 && dig->signature.version != (rpmuint8_t)4)
01126 {
01127 rpmlog(RPMLOG_ERR,
01128 _("skipping header with unverifiable V%u signature\n"),
01129 (unsigned) dig->signature.version);
01130 rc = RPMRC_FAIL;
01131 goto exit;
01132 }
01133
01134 ildl[0] = (rpmuint32_t) htonl(ril);
01135 ildl[1] = (rpmuint32_t) (regionEnd - dataStart);
01136 ildl[1] = (rpmuint32_t) htonl(ildl[1]);
01137
01138 op = pgpStatsAccumulator(dig, 10);
01139 (void) rpmswEnter(op, 0);
01140 dig->hdrctx = rpmDigestInit((pgpHashAlgo)dig->signature.hash_algo, RPMDIGEST_NONE);
01141
01142 b = NULL; nb = 0;
01143 (void) headerGetMagic(NULL, &b, &nb);
01144 if (b && nb > 0) {
01145 (void) rpmDigestUpdate(dig->hdrctx, b, nb);
01146 dig->nbytes += nb;
01147 }
01148
01149 b = (unsigned char *) ildl;
01150 nb = sizeof(ildl);
01151 (void) rpmDigestUpdate(dig->hdrctx, b, nb);
01152 dig->nbytes += nb;
01153
01154 b = (unsigned char *) pe;
01155 nb = (size_t) (htonl(ildl[0]) * sizeof(*pe));
01156 (void) rpmDigestUpdate(dig->hdrctx, b, nb);
01157 dig->nbytes += nb;
01158
01159 b = (unsigned char *) dataStart;
01160 nb = (size_t) htonl(ildl[1]);
01161 (void) rpmDigestUpdate(dig->hdrctx, b, nb);
01162 dig->nbytes += nb;
01163 (void) rpmswExit(op, dig->nbytes);
01164
01165 break;
01166 case RPMTAG_DSAHEADER:
01167
01168 xx = pgpPrtPkts(sig, info->count, dig, (_print_pkts & rpmIsDebug()));
01169 if (dig->signature.version != (rpmuint8_t)3
01170 && dig->signature.version != (rpmuint8_t)4)
01171 {
01172 rpmlog(RPMLOG_ERR,
01173 _("skipping header with unverifiable V%u signature\n"),
01174 (unsigned) dig->signature.version);
01175 rc = RPMRC_FAIL;
01176 goto exit;
01177 }
01178
01179 case RPMTAG_SHA1HEADER:
01180 ildl[0] = (rpmuint32_t) htonl(ril);
01181 ildl[1] = (rpmuint32_t) (regionEnd - dataStart);
01182 ildl[1] = (rpmuint32_t) htonl(ildl[1]);
01183
01184 op = pgpStatsAccumulator(dig, 10);
01185 (void) rpmswEnter(op, 0);
01186 dig->hdrsha1ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
01187
01188 b = NULL; nb = 0;
01189 (void) headerGetMagic(NULL, &b, &nb);
01190 if (b && nb > 0) {
01191 (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
01192 dig->nbytes += nb;
01193 }
01194
01195 b = (unsigned char *) ildl;
01196 nb = sizeof(ildl);
01197 (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
01198 dig->nbytes += nb;
01199
01200 b = (unsigned char *) pe;
01201 nb = (size_t) (htonl(ildl[0]) * sizeof(*pe));
01202 (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
01203 dig->nbytes += nb;
01204
01205 b = (unsigned char *) dataStart;
01206 nb = (size_t) htonl(ildl[1]);
01207 (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
01208 dig->nbytes += nb;
01209 (void) rpmswExit(op, dig->nbytes);
01210
01211 break;
01212 default:
01213 sig = _free(sig);
01214 break;
01215 }
01216
01217 buf[0] = '\0';
01218 rc = rpmVerifySignature(dig, buf);
01219
01220 buf[sizeof(buf)-1] = '\0';
01221 if (msg) *msg = xstrdup(buf);
01222
01223 if (_pkgio_debug)
01224 fprintf(stderr, "--> headerCheck #3: rc %d \"%s\"\n", rc, (msg ? *msg: ""));
01225 return rc;
01226 }
01227
01233 static size_t szHeader( const void * ptr)
01234
01235 {
01236 rpmuint32_t p[4];
01237 assert(ptr != NULL);
01238 memcpy(p, ptr, sizeof(p));
01239 return (8 + 8 + 16 * ntohl(p[2]) + ntohl(p[3]));
01240 }
01241
01242
01250 static rpmRC ckHeader( FD_t fd, const void * ptr,
01251 const char ** msg)
01252
01253
01254 {
01255 rpmRC rc = RPMRC_OK;
01256 Header h;
01257
01258 h = headerLoad((void *)ptr);
01259 if (h == NULL)
01260 rc = RPMRC_FAIL;
01261 (void)headerFree(h);
01262 h = NULL;
01263
01264 return rc;
01265 }
01266
01274 static rpmRC rpmReadHeader(FD_t fd, Header * hdrp,
01275 const char ** msg)
01276
01277
01278 {
01279 rpmxar xar = fdGetXAR(fd);
01280 pgpDig dig = pgpDigLink(fdGetDig(fd), "rpmReadHeader");
01281 char buf[BUFSIZ];
01282 rpmuint32_t block[4];
01283 rpmuint32_t il;
01284 rpmuint32_t dl;
01285 rpmuint32_t * ei = NULL;
01286 size_t uc = 0;
01287 unsigned char * b;
01288 size_t startoff;
01289 size_t nb;
01290 Header h = NULL;
01291 const char * origin = NULL;
01292 rpmRC rc = RPMRC_FAIL;
01293 int xx;
01294 static int map = 1;
01295
01296 if (_pkgio_debug)
01297 fprintf(stderr, "--> rpmReadHeader(%p, %p, %p)\n", fd, hdrp, msg);
01298
01299
01300 if (dig == NULL) {
01301 dig = pgpDigNew(0);
01302 (void) fdSetDig(fd, dig);
01303 }
01304
01305 buf[0] = '\0';
01306
01307 if (hdrp)
01308 *hdrp = NULL;
01309
01310 memset(block, 0, sizeof(block));
01311 if (xar != NULL) {
01312 const char item[] = "Header";
01313 if ((xx = rpmxarNext(xar)) != 0 || (xx = rpmxarPull(xar, item)) != 0) {
01314 (void) snprintf(buf, sizeof(buf),
01315 _("XAR file not found (or no XAR support)"));
01316 rc = RPMRC_NOTFOUND;
01317 goto exit;
01318 }
01319 }
01320
01321 startoff = fd->stats->ops[FDSTAT_READ].bytes;
01322 if ((xx = (int) timedRead(fd, (char *)block, sizeof(block))) != (int)sizeof(block)) {
01323
01324 if (xx == 0)
01325 rc = RPMRC_NOTFOUND;
01326 else
01327 (void) snprintf(buf, sizeof(buf),
01328 _("hdr size(%u): BAD, read returned %d"), (unsigned)sizeof(block), xx);
01329 goto exit;
01330 }
01331
01332 b = NULL;
01333 nb = 0;
01334 (void) headerGetMagic(NULL, &b, &nb);
01335 if (memcmp(block, b, nb)) {
01336 unsigned char * x = (unsigned char *) block;
01337
01338 (void) snprintf(buf, sizeof(buf), _("hdr magic: BAD, read %02x%02x%02x%02x%02x%02x%02x%02x"), x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7]);
01339
01340 goto exit;
01341 }
01342
01343 il = (rpmuint32_t)ntohl(block[2]);
01344 if (hdrchkTags(il)) {
01345 (void) snprintf(buf, sizeof(buf),
01346 _("hdr tags: BAD, no. of tags(%u) out of range"), (unsigned) il);
01347
01348 goto exit;
01349 }
01350 dl = (rpmuint32_t)ntohl(block[3]);
01351 if (hdrchkData(dl)) {
01352 (void) snprintf(buf, sizeof(buf),
01353 _("hdr data: BAD, no. of bytes(%u) out of range\n"), (unsigned) dl);
01354 goto exit;
01355 }
01356
01357
01358 nb = (il * sizeof(struct entryInfo_s)) + dl;
01359
01360 uc = sizeof(il) + sizeof(dl) + nb;
01361 if (map) {
01362 static const int prot = PROT_READ | PROT_WRITE;
01363 static const int flags = MAP_PRIVATE| MAP_ANONYMOUS;
01364 static const int fdno = -1;
01365 static const off_t off = 0;
01366
01367 ei = mmap(NULL, uc, prot, flags, fdno, off);
01368 if (ei == NULL || ei == (void *)-1)
01369 fprintf(stderr,
01370 "==> mmap(%p[%u], 0x%x, 0x%x, %d, 0x%x) error(%d): %s\n",
01371 NULL, uc, prot, flags, fdno, (unsigned)off,
01372 errno, strerror(errno));
01373 } else {
01374 ei = (rpmuint32_t *) xmalloc(uc);
01375 }
01376
01377 if ((xx = (int) timedRead(fd, (char *)&ei[2], nb)) != (int) nb) {
01378 (void) snprintf(buf, sizeof(buf),
01379 _("hdr blob(%u): BAD, read returned %d"), (unsigned)nb, xx);
01380 goto exit;
01381 }
01382 ei[0] = block[2];
01383 ei[1] = block[3];
01384
01385 if (map) {
01386 if (mprotect(ei, uc, PROT_READ) != 0)
01387 fprintf(stderr, "==> mprotect(%p[%u],0x%x) error(%d): %s\n",
01388 ei, uc, PROT_READ,
01389 errno, strerror(errno));
01390 }
01391
01392
01393 rc = headerCheck(dig, ei, uc, msg);
01394 if (rc != RPMRC_OK)
01395 goto exit;
01396
01397
01398 h = headerLoad(ei);
01399 if (h == NULL) {
01400 (void) snprintf(buf, sizeof(buf), _("hdr load: BAD\n"));
01401 goto exit;
01402 }
01403 if (map) {
01404 h->flags |= HEADERFLAG_MAPPED;
01405 h->flags |= HEADERFLAG_RDONLY;
01406 } else
01407 h->flags |= HEADERFLAG_ALLOCATED;
01408 ei = NULL;
01409
01410
01411
01412 origin = fdGetOPath(fd);
01413 if (origin != NULL) {
01414 const char * lpath = NULL;
01415 int ut = urlPath(origin, &lpath);
01416 ut = ut;
01417 if (lpath && *lpath != '/') {
01418 char * rpath = Realpath(origin, NULL);
01419 (void) headerSetOrigin(h, rpath);
01420 rpath = _free(rpath);
01421 } else
01422 (void) headerSetOrigin(h, origin);
01423 }
01424
01425 { struct stat * st = headerGetStatbuf(h);
01426 int saveno = errno;
01427 (void) Fstat(fd, st);
01428 errno = saveno;
01429 }
01430
01431 (void) headerSetStartOff(h, (rpmuint32_t)startoff);
01432 (void) headerSetEndOff(h, fd->stats->ops[FDSTAT_READ].bytes);
01433
01434 exit:
01435 if (hdrp && h && rc == RPMRC_OK)
01436 *hdrp = headerLink(h);
01437 if (ei != NULL && uc > 0) {
01438 if (map) {
01439 if (munmap(ei, uc) != 0)
01440 fprintf(stderr, "==> munmap(%p[%u]) error(%d): %s\n",
01441 ei, uc, errno, strerror(errno));
01442 ei = NULL;
01443 } else
01444 ei = _free(ei);
01445 }
01446 dig = pgpDigFree(dig, "rpmReadHeader");
01447 (void)headerFree(h);
01448 h = NULL;
01449
01450 if (msg != NULL && *msg == NULL && buf[0] != '\0') {
01451 buf[sizeof(buf)-1] = '\0';
01452 *msg = xstrdup(buf);
01453 }
01454
01455 if (_pkgio_debug)
01456 fprintf(stderr, "--> rpmReadHeader: rc %d \"%s\"\n", rc, (msg ? *msg: ""));
01457 return rc;
01458 }
01459
01467 static rpmRC rdHeader(FD_t fd, void * ptr,
01468 const char ** msg)
01469
01470
01471 {
01472 Header * hdrp = ptr;
01473
01474 return rpmReadHeader(fd, hdrp, msg);
01475
01476 }
01477
01485 static rpmRC wrHeader(FD_t fd, void * ptr,
01486 const char ** msg)
01487
01488
01489 {
01490 Header h = ptr;
01491 return rpmWriteHeader(fd, h, msg);
01492 }
01493
01494
01495
01496
01497 size_t rpmpkgSizeof(const char * fn, const void * ptr)
01498 {
01499 size_t len = 0;
01500
01501 if (!strcmp(fn, "Lead"))
01502 len = 96;
01503 else
01504 if (!strcmp(fn, "Signature")) {
01505 len = szHeader(ptr);
01506 len += ((8 - (len % 8)) % 8);
01507 } else
01508 if (!strcmp(fn, "Header"))
01509 len = szHeader(ptr);
01510 return len;
01511 }
01512
01513 rpmRC rpmpkgCheck(const char * fn, FD_t fd, const void * ptr, const char ** msg)
01514 {
01515 rpmRC rc = RPMRC_FAIL;
01516
01517 if (msg)
01518 *msg = NULL;
01519
01520 if (!strcmp(fn, "Header"))
01521 rc = ckHeader(fd, ptr, msg);
01522 return rc;
01523 }
01524
01525 rpmRC rpmpkgRead(const char * fn, FD_t fd, void * ptr, const char ** msg)
01526 {
01527 rpmRC rc = RPMRC_FAIL;
01528
01529 if (msg)
01530 *msg = NULL;
01531
01532 if (!strcmp(fn, "Lead"))
01533 rc = rdLead(fd, ptr, msg);
01534 else
01535 if (!strcmp(fn, "Signature"))
01536 rc = rdSignature(fd, ptr, msg);
01537 else
01538 if (!strcmp(fn, "Header"))
01539 rc = rdHeader(fd, ptr, msg);
01540 return rc;
01541 }
01542
01543 rpmRC rpmpkgWrite(const char * fn, FD_t fd, void * ptr, const char ** msg)
01544 {
01545 rpmRC rc = RPMRC_FAIL;
01546
01547 if (msg)
01548 *msg = NULL;
01549
01550 if (!strcmp(fn, "Lead"))
01551 rc = wrLead(fd, ptr, msg);
01552 else
01553 if (!strcmp(fn, "Signature"))
01554 rc = wrSignature(fd, ptr, msg);
01555 else
01556 if (!strcmp(fn, "Header"))
01557 rc = wrHeader(fd, ptr, msg);
01558 return rc;
01559 }