rpm  5.4.15
pkgio.c
Go to the documentation of this file.
1 
6 #include "system.h"
7 
8 #if defined(HAVE_MACHINE_TYPES_H)
9 # include <machine/types.h>
10 #endif
11 
12 #include <netinet/in.h>
13 
14 #define _RPMIOB_INTERNAL
15 #include <rpmiotypes.h>
16 #include <rpmio_internal.h>
17 #include <rpmcb.h>
18 #include <rpmbc.h> /* XXX beecrypt base64 */
19 #include <rpmmacro.h>
20 #define _RPMHKP_INTERNAL
21 #include <rpmhkp.h>
22 #include <rpmku.h>
23 
24 #define _RPMTAG_INTERNAL
25 #include "header_internal.h"
26 
27 #include <rpmdb.h>
28 #include <pkgio.h>
29 
30 #define _RPMTS_INTERNAL
31 #include "rpmts.h"
32 
33 #include <rpmxar.h>
34 
35 #include "signature.h"
36 #include "debug.h"
37 
38 /*@access rpmts @*/
39 /*@access rpmxar @*/
40 /*@access pgpDig @*/
41 /*@access pgpDigParams @*/
42 /*@access Header @*/ /* XXX compared with NULL */
43 /*@access entryInfo @*/
44 /*@access indexEntry @*/
45 /*@access FD_t @*/ /* XXX stealing digests */
46 /*@access FDSTAT_t @*/ /* XXX stealing digests */
47 
48 #ifdef __cplusplus
49 GENfree(struct rpmlead *)
50 GENfree(rpmuint8_t **)
51 GENfree(rpmuint32_t *)
52 #endif /* __cplusplus */
53 
54 /*@unchecked@*/
55 int _pkgio_debug = 0;
56 
59 /*@-exportheader@*/
60 /*@unused@*/ ssize_t timedRead(FD_t fd, /*@out@*/ void * bufptr, size_t length)
61  /*@globals fileSystem @*/
62  /*@modifies fd, *bufptr, fileSystem @*/;
63 #define timedRead (ufdio->read)
64 /*@=exportheader@*/
65 
66 /*===============================================*/
74 static
75 rpmRC rpmWriteHeader(FD_t fd, /*@null@*/ Header h, /*@null@*/ const char ** msg)
76  /*@globals fileSystem, internalState @*/
77  /*@modifies fd, h, *msg, fileSystem, internalState @*/
78 {
79  const void * uh = NULL;
80  size_t nb;
81  size_t length;
82  rpmRC rc = RPMRC_FAIL; /* assume failure */
83 
84 if (_pkgio_debug)
85 fprintf(stderr, "--> rpmWriteHeader(%p, %p, %p)\n", fd, h, msg);
86 
87  if (h == NULL) {
88  if (msg)
89  *msg = xstrdup(_("write of NULL header"));
90  goto exit;
91  }
92 
93  uh = headerUnload(h, &length);
94  if (uh == NULL) {
95  if (msg)
96  *msg = xstrdup(_("headerUnload failed"));
97  goto exit;
98  }
99 
100  { unsigned char * hmagic = NULL;
101  size_t nmagic = 0;
102 
103  (void) headerGetMagic(NULL, &hmagic, &nmagic);
104  nb = Fwrite(hmagic, sizeof(hmagic[0]), nmagic, fd);
105  if (nb != nmagic || Ferror(fd)) {
106  if (msg)
107  *msg = (nb > 0
108  ? xstrdup(_("short write of header magic"))
109  : xstrdup(Fstrerror(fd)) );
110  goto exit;
111  }
112  }
113 
114  /*@-sizeoftype@*/
115  nb = Fwrite(uh, sizeof(char), length, fd);
116  /*@=sizeoftype@*/
117  if (nb != length || Ferror(fd)) {
118  if (msg)
119  *msg = (nb > 0
120  ? xstrdup(_("short write of header"))
121  : xstrdup(Fstrerror(fd)) );
122  goto exit;
123  }
124  rc = RPMRC_OK;
125 
126 exit:
127  uh = _free(uh);
128  return rc;
129 }
130 
131 /*===============================================*/
132 
134 {
135  rpmop op = NULL;
136 
137  if (ts != NULL && (int)opx >= 0 && (int)opx < RPMTS_OP_MAX)
138  op = ts->ops + opx;
139 /*@-usereleased -compdef @*/
140  return op;
141 /*@=usereleased =compdef @*/
142 }
143 
145 {
146 /*@-onlytrans@*/
147  return pgpGetPubkey(rpmtsDig(ts));
148 /*@=onlytrans@*/
149 }
150 
152 {
153  rpmdb rdb = NULL;
154  if (ts != NULL) {
155  rdb = ts->rdb;
156  }
157 /*@-compdef -refcounttrans -usereleased @*/
158  return rdb;
159 /*@=compdef =refcounttrans =usereleased @*/
160 }
161 
163 {
164  static const char * _dbpath = NULL;
165  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
166  pgpDig dig = (pgpDig) (_dig ? _dig : rpmtsDig(ts));
167  pgpDigParams sigp = pgpGetSignature(dig);
168  pgpDigParams pubp = pgpGetPubkey(dig);
169  rpmRC res = RPMRC_NOKEY;
170  const char * pubkeysource = NULL;
171  rpmhkp hkp = NULL;
172  rpmbf awol;
173  rpmiob iob = NULL;
174  int krcache = 1; /* XXX assume pubkeys are cached in keyutils keyring. */
175 int validate = 0;
176  int xx;
177 
178 if (_rpmhkp_debug)
179 fprintf(stderr, "--> %s(%p,%p)\n", __FUNCTION__, ts, _dig);
180 
181 assert(dig != NULL);
182 assert(sigp != NULL);
183 assert(pubp != NULL);
184 /*@-sefparams@*/
185 assert(rpmtsDig(ts) == dig);
186 /*@=sefparams@*/
187  if (ts->hkp == NULL)
188  ts->hkp = rpmhkpNew(NULL, 0);
189  hkp = rpmhkpLink(ts->hkp);
190  awol = rpmbfLink(hkp->awol);
191 
192 #if 0
193 if (_rpmhkp_debug)
194 fprintf(stderr, "==> find sig id %08x %08x ts pubkey id %08x %08x\n",
195 pgpGrab(sigp->signid, 4), pgpGrab(sigp->signid+4, 4),
196 pgpGrab(hkp->signid, 4), pgpGrab(hkp->signid+4, 4));
197 #endif
198 
199  /* Lazy free of previous pubkey if pubkey does not match this signature. */
200  if (memcmp(sigp->signid, hkp->signid, sizeof(hkp->signid))) {
201 #if 0
202 if (_rpmhkp_debug)
203 fprintf(stderr, "*** free pkt %p[%d] id %08x %08x\n", hkp->pkt, hkp->pktlen, pgpGrab(hkp->signid, 4), pgpGrab(hkp->signid+4, 4));
204 #endif
205  hkp->pkt = _free(hkp->pkt);
206  hkp->pktlen = 0;
207  memset(hkp->signid, 0, sizeof(hkp->signid));
208  }
209 
210  /* Has this pubkey failed a previous lookup? */
211  if (hkp->pkt == NULL && awol != NULL
212  && rpmbfChk(awol, sigp->signid, sizeof(sigp->signid)))
213  goto leave;
214 
215  /* Try keyutils keyring lookup. */
216  if (hkp->pkt == NULL) {
217  iob = NULL;
218  switch (rpmkuFindPubkey(sigp, &iob)) {
219  case RPMRC_NOTFOUND:
220  case RPMRC_FAIL:
221  case RPMRC_NOTTRUSTED:
222  case RPMRC_NOKEY:
223  case RPMRC_NOSIG:
224  break;
225  case RPMRC_OK:
226  krcache = 0; /* XXX don't bother caching. */
227  hkp->pkt = (rpmuint8_t *)
228  memcpy(xmalloc(iob->blen), iob->b, iob->blen);
229  hkp->pktlen = iob->blen;
230  pubkeysource = xstrdup("keyutils");
231 validate = 0;
232  break;
233  }
234 if (_rpmhkp_debug)
235 fprintf(stderr, "\t%s: rpmku %p[%u]\n", __FUNCTION__, hkp->pkt, (unsigned) hkp->pktlen);
236  }
237 
238  /* Try rpmdb keyring lookup. */
239  if (_dbpath == NULL)
240  _dbpath = rpmGetPath("%{?_dbpath}", NULL);
241  if (hkp->pkt == NULL && *_dbpath != '\0') {
242  unsigned hx = 0xffffffff;
243  unsigned ix = 0xffffffff;
244  rpmmi mi;
245  Header h;
246 
247  /* XXX Do a lazy open if not done already. */
248  if (ts->rdb == NULL) {
249  xx = rpmdbOpen(ts->rootDir, &ts->rdb, ts->dbmode, (mode_t)0644);
250  if (xx)
252  _("cannot open Packages database in %s\n"), _dbpath);
253  }
254 
255  /* Retrieve the pubkey that matches the signature. */
256  he->tag = RPMTAG_PUBKEYS;
257 /*@-nullstate@*/
258  mi = rpmmiInit(rpmtsGetRdb(ts), RPMTAG_PUBKEYS, sigp->signid, sizeof(sigp->signid));
259 /*@=nullstate@*/
260  while ((h = rpmmiNext(mi)) != NULL) {
261  if (!headerGet(h, he, 0))
262  continue;
263  hx = rpmmiInstance(mi);
264  switch (he->t) {
265  default:
266  ix = 0xffffffff;
267  break;
269  ix = he->c - 1; /* XXX FIXME: assumes last pubkey */
270  if (b64decode(he->p.argv[ix], (void **)&hkp->pkt, &hkp->pktlen))
271  ix = 0xffffffff;
272  break;
273  }
274  he->p.ptr = _free(he->p.ptr);
275  break;
276  }
277  mi = rpmmiFree(mi);
278 
279  if (ix < 0xffffffff) {
280  char hnum[64];
281  sprintf(hnum, "h#%u[%u]", hx, ix);
282  pubkeysource = xstrdup(hnum);
283 validate = -1; /* XXX rpmhkpValidate is prerequisite for rpmhkpFindKey */
284  } else {
285  hkp->pkt = _free(hkp->pkt);
286  hkp->pktlen = 0;
287  }
288 if (_rpmhkp_debug)
289 fprintf(stderr, "\t%s: rpmdb %p[%u]\n", __FUNCTION__, hkp->pkt, (unsigned) hkp->pktlen);
290  }
291 
292  /* Try autosign package pubkey (if present). */
293  if (hkp->pkt == NULL && dig->pub && dig->publen > 0) {
294  uint8_t keyid[8];
295 
296  xx = pgpPubkeyFingerprint((const rpmuint8_t *)dig->pub, dig->publen, keyid);
297  if (!memcmp(sigp->signid, keyid, sizeof(keyid))) {
298  hkp->pkt = (uint8_t *) dig->pub; dig->pub = NULL;
299  hkp->pktlen = dig->publen; dig->publen = 0;
300  pubkeysource = xstrdup("package");
301 validate = -1; /* XXX rpmhkpValidate is prerequisite for rpmhkpFindKey */
302 if (_rpmhkp_debug)
303 fprintf(stderr, "\t%s: auto %p[%u]\n", __FUNCTION__, hkp->pkt, (unsigned) hkp->pktlen);
304  }
305  }
306 
307  /* Try keyserver lookup. */
308  if (hkp->pkt == NULL) {
309  const char * fn = rpmExpand("%{_hkp_keyserver_query}", "0x",
310  pgpHexStr(sigp->signid, sizeof(sigp->signid)), NULL);
311 
312  xx = (fn && *fn != '%')
313  ? (pgpReadPkts(fn, &hkp->pkt, &hkp->pktlen) != PGPARMOR_PUBKEY)
314  : 1; /* XXX assume failure */
315  fn = _free(fn);
316  if (xx) {
317  hkp->pkt = _free(hkp->pkt);
318  hkp->pktlen = 0;
319  } else {
320  /* Save new pubkey in local ts keyring for delayed import. */
321  pubkeysource = xstrdup("keyserver");
322 validate = 1;
323  }
324 if (_rpmhkp_debug)
325 fprintf(stderr, "\t%s: rpmhkp %p[%u]\n", __FUNCTION__, hkp->pkt, (unsigned) hkp->pktlen);
326  }
327 
328 #ifdef NOTYET
329  /* Try filename from macro lookup. */
330  if (hkp->pkt == NULL) {
331  const char * fn = rpmExpand("%{_gpg_pubkey}", NULL);
332 
333  xx = 0;
334  if (fn && *fn != '%')
335  xx = (pgpReadPkts(fn, &hkp->pkt, &hkp->pktlen) != PGPARMOR_PUBKEY);
336  fn = _free(fn);
337  if (xx) {
338  hkp->pkt = _free(hkp->pkt);
339  hkp->pktlen = 0;
340  } else {
341  pubkeysource = xstrdup("macro");
342  }
343  }
344 #endif
345 
346  /* Was a matching pubkey found? */
347  if (hkp->pkt == NULL || hkp->pktlen == 0)
348  goto exit;
349 if (_rpmhkp_debug)
350 fprintf(stderr, "\t%s: match %p[%u]\n", __FUNCTION__, hkp->pkt, (unsigned) hkp->pktlen);
351 
352  /* Split the result into packet array. */
353 hkp->pkts = _free(hkp->pkts); /* XXX memleaks */
354 hkp->npkts = 0;
355  xx = pgpGrabPkts(hkp->pkt, hkp->pktlen, &hkp->pkts, &hkp->npkts);
356 
357  if (!xx)
358  xx = pgpPubkeyFingerprint(hkp->pkt, hkp->pktlen, hkp->keyid);
359  memcpy(pubp->signid, hkp->keyid, sizeof(pubp->signid)); /* XXX useless */
360 
361  /* Validate pubkey self-signatures. */
362  /* XXX need at least 3 packets to validate a pubkey */
363  if (validate) {
364  rpmRC rc = rpmhkpValidate(hkp, NULL);
365  switch (rc) {
366  case RPMRC_OK:
367  break;
368  case RPMRC_NOKEY:
369  if (validate < 0) /* XXX ignore NOKEY w rpmdb pubkey. */
370  break;
371  /*@fallthrough@*/
372  case RPMRC_NOTFOUND:
373  case RPMRC_FAIL: /* XXX remap to NOTFOUND? */
374  case RPMRC_NOTTRUSTED:
375  default:
376 if (_rpmhkp_debug)
377 fprintf(stderr, "*** rpmhkpValidate: validate %d rc %d\n", validate, rc);
378  res = rc;
379  goto exit;
380  }
381  }
382 
383  /* Retrieve parameters from pubkey/subkey packet(s). */
384  xx = rpmhkpFindKey(hkp, dig, sigp->signid, sigp->pubkey_algo);
385 
386 #ifdef DYING
387 if (_rpmhkp_debug)
388 _rpmhkpDumpDig(__FUNCTION__, dig, NULL);
389 #endif
390 
391  /* Do the parameters match the signature? */
392  if (sigp->pubkey_algo == pubp->pubkey_algo
393  && !memcmp(sigp->signid, pubp->signid, sizeof(sigp->signid)) )
394  {
395 
396  /* Save the pubkey in the keyutils keyring. */
397  if (krcache) {
398  if (iob == NULL) {
399  iob = rpmiobNew(hkp->pktlen);
400  iob->b = (rpmuint8_t *)memcpy(iob->b, hkp->pkt, iob->blen);
401  }
402  (void) rpmkuStorePubkey(sigp, iob);
403 if (_rpmhkp_debug)
404 fprintf(stderr, "\t%s: rpmku %p[%u]\n", __FUNCTION__, hkp->pkt, (unsigned) hkp->pktlen);
405  }
406 
407  /* Pubkey packet looks good, save the signer id. */
408  memcpy(hkp->signid, pubp->signid, sizeof(hkp->signid));
409 
410  if (pubkeysource)
411  rpmlog(RPMLOG_DEBUG, "========== %s pubkey id %08x %08x (%s)\n",
412  _pgpPubkeyAlgo2Name(sigp->pubkey_algo),
413  pgpGrab(sigp->signid, 4), pgpGrab(sigp->signid+4, 4),
414  pubkeysource);
415 
416  res = RPMRC_OK;
417 
418  }
419 
420 exit:
421  pubkeysource = _free(pubkeysource);
422  if (res != RPMRC_OK) {
423  hkp->pkt = _free(hkp->pkt);
424  hkp->pktlen = 0;
425  if (awol)
426  xx = rpmbfAdd(awol, sigp->signid, sizeof(sigp->signid));
427  }
428 
429 leave:
430  (void) rpmbfFree(awol);
431  (void) rpmhkpFree(hkp);
432 
433 if (_rpmhkp_debug)
434 fprintf(stderr, "<-- %s(%p,%p) res %d\n", __FUNCTION__, ts, _dig, res);
435 
436 /*@-nullstate@*/
437  return res;
438 /*@=nullstate@*/
439 }
440 
442 {
443 /*@-mods@*/ /* FIX: hide lazy malloc for now */
444  if (ts->dig == NULL) {
445  ts->dig = pgpDigNew(RPMVSF_DEFAULT, (pgpPubkeyAlgo)0);
446 /*@-refcounttrans@*/
447  (void) pgpSetFindPubkey(ts->dig, (int (*)(void *, void *))rpmtsFindPubkey, ts);
448 /*@=refcounttrans@*/
449  }
450 /*@=mods@*/
451 /*@-compdef -retexpose -usereleased@*/
452  return ts->dig;
453 /*@=compdef =retexpose =usereleased@*/
454 }
455 
457 {
458  if (ts && ts->dig) {
459  rpmtsOpX opx;
460  opx = RPMTS_OP_DIGEST;
461  (void) rpmswAdd(rpmtsOp(ts, opx), (rpmop)pgpStatsAccumulator(ts->dig, opx));
462  opx = RPMTS_OP_SIGNATURE;
463  (void) rpmswAdd(rpmtsOp(ts, opx), (rpmop)pgpStatsAccumulator(ts->dig, opx));
464 /*@-onlytrans@*/
465  (void) pgpDigFree(ts->dig);
466  ts->dig = NULL; /* XXX make sure the ptr is __REALLY__ gone */
467 /*@=onlytrans@*/
468  }
469 }
470 
471 /*===============================================*/
472 
479 struct rpmlead {
480  unsigned char magic[4];
481  unsigned char major;
482  unsigned char minor;
483  unsigned short type;
484  unsigned short archnum;
485  char name[66];
486  unsigned short osnum;
487  unsigned short signature_type;
488 /*@unused@*/
489  char reserved[16];
490 } ;
491 
492 /*@-type@*/
493 /*@unchecked@*/ /*@observer@*/
494 static unsigned char lead_magic[] = {
495  0xed, 0xab, 0xee, 0xdb, 0x00, 0x00, 0x00, 0x00
496 };
497 /*@=type@*/
498 
499 /* The lead needs to be 8 byte aligned */
500 
508 static rpmRC wrLead(FD_t fd, const void * ptr, /*@null@*/ const char ** msg)
509  /*@globals fileSystem @*/
510  /*@modifies fd, fileSystem @*/
511 {
512  struct rpmlead l;
513 
514 if (_pkgio_debug)
515 fprintf(stderr, "--> wrLead(%p, %p, %p)\n", fd, ptr, msg);
516 
517  memcpy(&l, ptr, sizeof(l));
518 
519  /* Set some sane defaults */
520  if ((int)l.major == 0)
521  l.major = (unsigned char) 3;
522  if (l.signature_type == 0)
523  l.signature_type = 5; /* RPMSIGTYPE_HEADERSIG */
524  if (msg && *msg)
525  (void) strncpy(l.name, *msg, sizeof(l.name));
526 
527  memcpy(&l.magic, lead_magic, sizeof(l.magic));
528  l.type = (unsigned short) htons(l.type);
529  l.archnum = (unsigned short) htons(l.archnum);
530  l.osnum = (unsigned short) htons(l.osnum);
531  l.signature_type = (unsigned short) htons(l.signature_type);
532 
533  if (Fwrite(&l, 1, sizeof(l), fd) != sizeof(l))
534  return RPMRC_FAIL;
535 
536  return RPMRC_OK;
537 }
538 
546 static rpmRC rdLead(FD_t fd, /*@out@*/ /*@null@*/ void * ptr,
547  /*@null@*/ const char ** msg)
548  /*@globals fileSystem @*/
549  /*@modifies fd, *ptr, *msg, fileSystem @*/
550 {
551  rpmxar xar = fdGetXAR(fd);
552  struct rpmlead ** leadp = (struct rpmlead **) ptr;
553  struct rpmlead * l = (struct rpmlead *) xcalloc(1, sizeof(*l));
554  char buf[BUFSIZ];
555  rpmRC rc = RPMRC_FAIL; /* assume failure */
556  int xx;
557 
558 if (_pkgio_debug)
559 fprintf(stderr, "--> rdLead(%p, %p, %p)\n", fd, ptr, msg);
560 
561  buf[0] = '\0';
562  if (leadp != NULL) *leadp = NULL;
563 
564  /* Read the first 96 bytes of the file. */
565  if ((xx = (int) timedRead(fd, (char *)l, sizeof(*l))) != (int) sizeof(*l)) {
566  if (Ferror(fd)) {
567  (void) snprintf(buf, sizeof(buf),
568  _("lead size(%u): BAD, read(%d), %s(%d)"),
569  (unsigned)sizeof(*l), xx, Fstrerror(fd), errno);
570  rc = RPMRC_FAIL;
571  } else {
572  (void) snprintf(buf, sizeof(buf),
573  _("lead size(%u): BAD, read(%d), %s(%d)"),
574  (unsigned)sizeof(*l), xx, strerror(errno), errno);
575  rc = RPMRC_NOTFOUND;
576  }
577  goto exit;
578  }
579 
580  /* Attach rpmxar handler to fd if this is a xar archive. */
581  if (xar == NULL) {
582  unsigned char * bh = (unsigned char *)l;
583  if (bh[0] == 'x' && bh[1] == 'a' && bh[2] == 'r' && bh[3] == '!') {
584  const char * fn = fdGetOPath(fd);
585 assert(fn != NULL);
586  xar = rpmxarNew(fn, "r");
587  fdSetXAR(fd, xar);
588  (void) rpmxarFree(xar, "rdLead");
589  }
590  }
591 
592  /* With XAR, read lead from a xar archive file called "Lead". */
593  xar = fdGetXAR(fd);
594  if (xar != NULL) {
595  unsigned char *b = NULL;
596  size_t nb = 0;
597  const char item[] = "Lead";
598  if ((xx = rpmxarNext(xar)) != 0 || (xx = rpmxarPull(xar, item)) != 0) {
599  (void) snprintf(buf, sizeof(buf),
600  _("XAR file not found (or no XAR support)"));
601  rc = RPMRC_NOTFOUND;
602  goto exit;
603  }
604  (void) rpmxarSwapBuf(xar, NULL, 0, &b, &nb);
605  if (nb != sizeof(*l)) {
606  (void) snprintf(buf, sizeof(buf),
607  _("lead size(%u): BAD, xar read(%u)"),
608  (unsigned)sizeof(*l), (unsigned)nb);
609  b = _free(b);
610  rc = RPMRC_FAIL;
611  goto exit;
612  }
613  memcpy(l, b, nb);
614  b = _free(b);
615  }
616 
617  l->type = (unsigned short) ntohs(l->type);
618  l->archnum = (unsigned short) ntohs(l->archnum);
619  l->osnum = (unsigned short) ntohs(l->osnum);
620  l->signature_type = (unsigned short) ntohs(l->signature_type);
621 
622  if (memcmp(l->magic, lead_magic, sizeof(l->magic))) {
623 /*@+charint@*/
624  (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]);
625 /*@=charint@*/
626  rc = RPMRC_NOTFOUND;
627  goto exit;
628  }
629 
630  switch (l->major) {
631  default:
632  (void) snprintf(buf, sizeof(buf),
633  _("lead version(%u): UNSUPPORTED"), (unsigned) l->major);
634  rc = RPMRC_NOTFOUND;
635  goto exit;
636  /*@notreached@*/ break;
637  case 3:
638  case 4:
639  break;
640  }
641 
642  if (l->signature_type != 5) { /* RPMSIGTYPE_HEADERSIG */
643  (void) snprintf(buf, sizeof(buf),
644  _("sigh type(%u): UNSUPPORTED"), (unsigned) l->signature_type);
645  rc = RPMRC_NOTFOUND;
646  goto exit;
647  }
648 
649  rc = RPMRC_OK;
650 
651 exit:
652  if (rc == RPMRC_OK && leadp != NULL)
653  *leadp = l;
654  else
655  /*@-dependenttrans@*/ l = _free(l); /*@=dependenttrans@*/
656 
657  if (msg != NULL && buf[0] != '\0') {
658  buf[sizeof(buf)-1] = '\0';
659  *msg = xstrdup(buf);
660  }
661  return rc;
662 }
663 
664 /*===============================================*/
665 
673 static rpmRC wrSignature(FD_t fd, void * ptr,
674  /*@unused@*/ /*@null@*/ const char ** msg)
675  /*@globals fileSystem, internalState @*/
676  /*@modifies fd, ptr, *msg, fileSystem, internalState @*/
677 {
678  Header sigh = (Header) ptr;
679  static unsigned char zero[8]
680  = { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' };
681  size_t sigSize;
682  size_t pad;
683  rpmRC rc = RPMRC_OK;
684 
685 if (_pkgio_debug)
686 fprintf(stderr, "--> wrSignature(%p, %p, %p)\n", fd, ptr, msg);
687 
688  rc = rpmWriteHeader(fd, sigh, msg);
689  if (rc != RPMRC_OK)
690  return rc;
691 
692  sigSize = headerSizeof(sigh);
693  pad = (8 - (sigSize % 8)) % 8;
694  if (pad) {
695  if (Fwrite(zero, sizeof(zero[0]), pad, fd) != pad)
696  rc = RPMRC_FAIL;
697  }
698  rpmlog(RPMLOG_DEBUG, D_("Signature: size(%u)+pad(%u)\n"), (unsigned)sigSize, (unsigned)pad);
699  return rc;
700 }
701 
710 static inline rpmRC printSize(FD_t fd, size_t siglen, size_t pad, size_t datalen)
711  /*@globals fileSystem, internalState @*/
712  /*@modifies fileSystem, internalState @*/
713 {
714  struct stat sb, * st = &sb;
715  size_t expected;
716  size_t nl = rpmpkgSizeof("Lead", NULL);
717 
718 #ifndef DYING /* XXX Fstat(2) contentLength not gud enuf yet. */
719  int fdno = Fileno(fd);
720  /* HACK: workaround for davRead wiring. */
721  if (fdno == 123456789) {
722 /*@-type@*/
723  st->st_size = 0;
724  st->st_size -= nl + siglen + pad + datalen;
725 /*@=type@*/
726  } else
727 #endif
728  if (Fstat(fd, st) < 0)
729  return RPMRC_FAIL;
730 
731  expected = nl + siglen + pad + datalen;
733  D_("Expected size: %12lu = lead(%u)+sigs(%u)+pad(%u)+data(%lu)\n"),
734  (unsigned long)expected,
735  (unsigned)nl, (unsigned) siglen, (unsigned) pad,
736  (unsigned long)datalen);
738  D_(" Actual size: %12lu\n"), (unsigned long)st->st_size);
739 
740  return RPMRC_OK;
741 }
742 
750 static rpmRC rdSignature(FD_t fd, /*@out@*/ /*@null@*/ void * ptr,
751  /*@null@*/ const char ** msg)
752  /*@globals fileSystem, internalState @*/
753  /*@modifies *ptr, *msg, fileSystem, internalState @*/
754 {
755 rpmxar xar = fdGetXAR(fd);
756  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
757  Header * sighp = (Header *) ptr;
758  char buf[BUFSIZ];
759  rpmuint32_t block[4];
760  rpmuint32_t il;
761  rpmuint32_t dl;
762  rpmuint32_t * ei = NULL;
763  entryInfo pe;
764  size_t startoff;
765  size_t nb;
766  rpmuint32_t ril = 0;
767  indexEntry entry = (indexEntry)
768  memset(alloca(sizeof(*entry)), 0, sizeof(*entry));
769  entryInfo info = (entryInfo)
770  memset(alloca(sizeof(*info)), 0, sizeof(*info));
771  unsigned char * dataStart;
772  unsigned char * dataEnd = NULL;
773  Header sigh = NULL;
774  rpmRC rc = RPMRC_FAIL; /* assume failure */
775  int xx;
776  rpmuint32_t i;
777  static int map = 1;
778 
779 if (_pkgio_debug)
780 fprintf(stderr, "--> rdSignature(%p, %p, %p)\n", fd, ptr, msg);
781 
782  buf[0] = '\0';
783  if (sighp)
784  *sighp = NULL;
785 
786  memset(block, 0, sizeof(block));
787  if (xar != NULL) {
788  const char item[] = "Signature";
789  if ((xx = rpmxarNext(xar)) != 0 || (xx = rpmxarPull(xar, item)) != 0) {
790  (void) snprintf(buf, sizeof(buf),
791  _("XAR file not found (or no XAR support)"));
792  rc = RPMRC_NOTFOUND;
793  goto exit;
794  }
795  }
796  startoff = fd->stats->ops[FDSTAT_READ].bytes;
797  if ((xx = (int) timedRead(fd, (char *)block, sizeof(block))) != (int) sizeof(block)) {
798  (void) snprintf(buf, sizeof(buf),
799  _("sigh size(%d): BAD, read returned %d"), (int)sizeof(block), xx);
800  goto exit;
801  }
802 
803  { unsigned char * hmagic = NULL;
804  size_t nmagic = 0;
805 
806  (void) headerGetMagic(NULL, &hmagic, &nmagic);
807 
808  if (memcmp(block, hmagic, nmagic)) {
809  unsigned char * x = (unsigned char *)block;
810 /*@+charint@*/
811  (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]);
812 /*@=charint@*/
813  goto exit;
814  }
815  }
816  il = (rpmuint32_t) ntohl(block[2]);
817  if (il > 32) {
818  (void) snprintf(buf, sizeof(buf),
819  _("sigh tags: BAD, no. of tags(%u) out of range"), (unsigned) il);
820  goto exit;
821  }
822  dl = (rpmuint32_t) ntohl(block[3]);
823  if (dl > 8192) {
824  (void) snprintf(buf, sizeof(buf),
825  _("sigh data: BAD, no. of bytes(%u) out of range"), (unsigned) dl);
826  goto exit;
827  }
828 
829 /*@-sizeoftype@*/
830  nb = (il * sizeof(struct entryInfo_s)) + dl;
831 /*@=sizeoftype@*/
832  if (map) {
833  size_t pvlen = (sizeof(il) + sizeof(dl) + nb);
834  static const int prot = PROT_READ | PROT_WRITE;
835  static const int flags = MAP_PRIVATE| MAP_ANONYMOUS;
836  static const int fdno = -1;
837  static const off_t off = 0;
838 
839  ei = (rpmuint32_t *) mmap(NULL, pvlen, prot, flags, fdno, off);
840 assert(ei != NULL && ei != (void *)-1); /* coverity #1214082 */
841  if (ei == NULL || ei == (void *)-1)
842  fprintf(stderr,
843  "==> mmap(%p[%u], 0x%x, 0x%x, %d, 0x%x) error(%d): %s\n",
844  NULL, (unsigned)pvlen, prot, flags, fdno, (unsigned)off,
845  errno, strerror(errno));
846  } else {
847  size_t pvlen = (sizeof(il) + sizeof(dl) + nb);
848  ei = (rpmuint32_t *) xmalloc(pvlen);
849  }
850 
851  if ((xx = (int) timedRead(fd, (char *)&ei[2], nb)) != (int) nb) {
852  (void) snprintf(buf, sizeof(buf),
853  _("sigh blob(%u): BAD, read returned %d"), (unsigned) nb, xx);
854  goto exit;
855  }
856  ei[0] = block[2];
857  ei[1] = block[3];
858 
859  if (map) {
860  size_t pvlen = (sizeof(il) + sizeof(dl) + nb);
861  if (mprotect(ei, pvlen, PROT_READ) != 0)
862  fprintf(stderr, "==> mprotect(%p[%u],0x%x) error(%d): %s\n",
863  ei, (unsigned)pvlen, PROT_READ,
864  errno, strerror(errno));
865  }
866 
867  pe = (entryInfo) &ei[2];
868  dataStart = (unsigned char *) (pe + il);
869 
870  /* Check (and convert) the 1st tag element. */
871  xx = headerVerifyInfo(1, dl, pe, &entry->info, 0);
872  if (xx != -1) {
873  (void) snprintf(buf, sizeof(buf),
874  _("tag[%d]: BAD, tag %u type %u offset %d count %u"),
875  0, (unsigned) entry->info.tag, (unsigned) entry->info.type,
876  (int)entry->info.offset, (unsigned) entry->info.count);
877  goto exit;
878  }
879 
880  /* Is there an immutable header region tag? */
881 /*@-sizeoftype@*/
882  if (entry->info.tag == RPMTAG_HEADERSIGNATURES)
883  {
884  /* Is the region tag sane? */
885  if (!(entry->info.type == REGION_TAG_TYPE
886  && entry->info.count == (rpmTagCount)REGION_TAG_COUNT))
887  {
888  (void) snprintf(buf, sizeof(buf),
889  _("region tag: BAD, tag %u type %u offset %d count %u"),
890  (unsigned) entry->info.tag, (unsigned) entry->info.type,
891  (int)entry->info.offset, (unsigned) entry->info.count);
892  goto exit;
893  }
894 /*@=sizeoftype@*/
895 
896 /*
897  * XXX http://mysql.mirrors.pair.com/Downloads/MySQL-5.0/MySQL-client-community-5.0.51a-0.rhel4.i386.rpm
898  * built by rpm-4.3.3 (from REL4) has entry->info.offset == 0.
899  */
900 assert(entry->info.offset >= 0); /* XXX insurance */
901  if (entry->info.offset >= (rpmint32_t)dl) {
902  (void) snprintf(buf, sizeof(buf),
903  _("region offset: BAD, tag %u type %u offset %d count %u"),
904  (unsigned) entry->info.tag, (unsigned) entry->info.type,
905  (int)entry->info.offset, (unsigned) entry->info.count);
906  goto exit;
907  }
908 
909  /* Is there an immutable header region tag trailer? */
910  dataEnd = dataStart + entry->info.offset;
911 /*@-sizeoftype@*/
912  (void) memcpy(info, dataEnd, REGION_TAG_COUNT);
913  /* XXX Really old packages have HEADER_IMAGE, not HEADER_SIGNATURES. */
914  if (info->tag == (rpmuint32_t) htonl(RPMTAG_HEADERIMAGE)) {
916  info->tag = (rpmTag) stag;
917  memcpy(dataEnd, &stag, sizeof(stag));
918  }
919  dataEnd += REGION_TAG_COUNT;
920 
921  xx = headerVerifyInfo(1, il * sizeof(*pe), info, &entry->info, 1);
922  if (xx != -1 ||
923  !(entry->info.tag == RPMTAG_HEADERSIGNATURES
924  && entry->info.type == REGION_TAG_TYPE
925  && entry->info.count == (rpmTagCount)REGION_TAG_COUNT))
926  {
927  (void) snprintf(buf, sizeof(buf),
928  _("region trailer: BAD, tag %u type %u offset %d count %u"),
929  (unsigned) entry->info.tag, (unsigned) entry->info.type,
930  (int)entry->info.offset, (unsigned) entry->info.count);
931  goto exit;
932  }
933 /*@=sizeoftype@*/
934  memset(info, 0, sizeof(*info));
935 
936  /* Is the no. of tags in the region less than the total no. of tags? */
937  ril = (rpmuint32_t) (entry->info.offset/sizeof(*pe));
938  if ((entry->info.offset % sizeof(*pe)) || ril > il) {
939  (void) snprintf(buf, sizeof(buf),
940  _("region size: BAD, ril(%u) > il(%u)"), (unsigned) ril, (unsigned) il);
941  goto exit;
942  }
943  }
944 
945  /* Sanity check signature tags */
946  memset(info, 0, sizeof(*info));
947  for (i = 1; i < (unsigned) il; i++) {
948  xx = headerVerifyInfo(1, dl, pe+i, &entry->info, 0);
949  if (xx != -1) {
950  (void) snprintf(buf, sizeof(buf),
951  _("sigh tag[%u]: BAD, tag %u type %u offset %d count %u"),
952  (unsigned) i, (unsigned) entry->info.tag, (unsigned) entry->info.type,
953  (int)entry->info.offset, (unsigned) entry->info.count);
954  goto exit;
955  }
956  }
957 
958  /* OK, blob looks sane, load the header. */
959  sigh = headerLoad(ei);
960  if (sigh == NULL) {
961  (void) snprintf(buf, sizeof(buf), _("sigh load: BAD"));
962  goto exit;
963  }
964  if (map) {
965  sigh->flags |= HEADERFLAG_MAPPED;
966  sigh->flags |= HEADERFLAG_RDONLY;
967  } else
968  sigh->flags |= HEADERFLAG_ALLOCATED;
969  sigh->flags |= HEADERFLAG_SIGNATURE;
970 
971  { size_t sigSize = headerSizeof(sigh);
972  size_t pad = (8 - (sigSize % 8)) % 8; /* 8-byte pad */
973 
974  /* Position at beginning of header. */
975  if (pad && (xx = (int) timedRead(fd, (char *)block, pad)) != (int) pad)
976  {
977  (void) snprintf(buf, sizeof(buf),
978  _("sigh pad(%u): BAD, read %d bytes"), (unsigned) pad, xx);
979  goto exit;
980  }
981 
982  /* Print package component sizes. */
983 
984  he->tag = (rpmTag) RPMSIGTAG_SIZE;
985  xx = headerGet(sigh, he, 0);
986  if (xx) {
987  size_t datasize = he->p.ui32p[0];
988  rc = printSize(fd, sigSize, pad, datasize);
989  if (rc != RPMRC_OK)
990  (void) snprintf(buf, sizeof(buf),
991  _("sigh sigSize(%u): BAD, Fstat(2) failed"), (unsigned) sigSize);
992  }
993  he->p.ptr = _free(he->p.ptr);
994  }
995  (void) headerSetStartOff(sigh, (rpmuint32_t)startoff);
996  (void) headerSetEndOff(sigh, fd->stats->ops[FDSTAT_READ].bytes);
997 
998 exit:
999  if (sighp && sigh && rc == RPMRC_OK)
1000  *sighp = headerLink(sigh);
1001  (void)headerFree(sigh);
1002  sigh = NULL;
1003 
1004  if (msg != NULL) {
1005  buf[sizeof(buf)-1] = '\0';
1006  *msg = xstrdup(buf);
1007  }
1008 
1009  return rc;
1010 }
1011 
1012 /*===============================================*/
1013 static int hBlobDigest(const void * uh, pgpDig dig, pgpHashAlgo hash_algo,
1014  const unsigned char * regionEnd, rpmuint32_t ril, DIGEST_CTX * ctxp)
1015 {
1016  rpmuint32_t * ei = (rpmuint32_t *) uh;
1017  rpmuint32_t il = (rpmuint32_t) ntohl(ei[0]);
1018  rpmuint32_t dl = (rpmuint32_t) ntohl(ei[1]);
1019  entryInfo pe = (entryInfo) &ei[2];
1020  rpmuint32_t ildl[2];
1021  const unsigned char * dataStart = (const unsigned char *) (pe + il);
1022  rpmop op;
1023  unsigned char * b = NULL;
1024  size_t nb = 0;
1025  int xx = 0;
1026 
1027  (void)dl;
1028 
1029  ildl[0] = (rpmuint32_t) htonl(ril);
1030  ildl[1] = (rpmuint32_t) (regionEnd - dataStart);
1031  ildl[1] = (rpmuint32_t) htonl(ildl[1]);
1032 
1033  op = (rpmop) pgpStatsAccumulator(dig, 10); /* RPMTS_OP_DIGEST */
1034  (void) rpmswEnter(op, 0);
1035  *ctxp = rpmDigestInit(hash_algo, RPMDIGEST_NONE);
1036 
1037  (void) headerGetMagic(NULL, &b, &nb);
1038  if (b && nb > 0) {
1039  (void) rpmDigestUpdate(*ctxp, b, nb);
1040  dig->nbytes += nb;
1041  }
1042 
1043  b = (unsigned char *) ildl;
1044  nb = sizeof(ildl);
1045  (void) rpmDigestUpdate(*ctxp, b, nb);
1046  dig->nbytes += nb;
1047 
1048  b = (unsigned char *) pe;
1049  nb = (size_t) (htonl(ildl[0]) * sizeof(*pe));
1050  (void) rpmDigestUpdate(*ctxp, b, nb);
1051  dig->nbytes += nb;
1052 
1053  b = (unsigned char *) dataStart;
1054  nb = (size_t) htonl(ildl[1]);
1055  (void) rpmDigestUpdate(*ctxp, b, nb);
1056  dig->nbytes += nb;
1057  (void) rpmswExit(op, dig->nbytes);
1058 
1059  return xx;
1060 }
1061 
1075 rpmRC headerCheck(pgpDig dig, const void * uh, size_t uc, const char ** msg)
1076 {
1077  char buf[8*BUFSIZ];
1078  rpmuint32_t * ei = (rpmuint32_t *) uh;
1079  rpmuint32_t il = (rpmuint32_t) ntohl(ei[0]);
1080  rpmuint32_t dl = (rpmuint32_t) ntohl(ei[1]);
1081 /*@-castexpose@*/
1082  entryInfo pe = (entryInfo) &ei[2];
1083 /*@=castexpose@*/
1084  rpmuint32_t ildl[2];
1085  size_t pvlen = sizeof(ildl) + (il * sizeof(*pe)) + dl;
1086  const unsigned char * dataStart = (const unsigned char *) (pe + il);
1087  indexEntry entry = (indexEntry)
1088  memset(alloca(sizeof(*entry)), 0, sizeof(*entry));
1089  entryInfo info = (entryInfo)
1090  memset(alloca(sizeof(*info)), 0, sizeof(*info));
1091  const void * sig = NULL;
1093  size_t siglen = 0;
1094  int blen;
1095  rpmuint32_t ril = 0;
1096  const unsigned char * regionEnd = NULL;
1097  rpmRC rc = RPMRC_FAIL; /* assume failure */
1098  int xx;
1099  rpmuint32_t i;
1100 pgpPkt pp = (pgpPkt) alloca(sizeof(*pp));
1101 size_t pleft;
1102 
1103 if (_pkgio_debug)
1104 fprintf(stderr, "--> headerCheck(%p, %p[%u], %p)\n", dig, uh, (unsigned) uc, msg);
1105 
1106  buf[0] = '\0';
1107 
1108  /* Is the blob the right size? */
1109  if (uc > 0 && pvlen != uc) {
1110  (void) snprintf(buf, sizeof(buf),
1111  _("blob size(%d): BAD, 8 + 16 * il(%u) + dl(%u)"),
1112  (int)uc, (unsigned)il, (unsigned)dl);
1113  goto exit;
1114  }
1115 
1116  /* Check (and convert) the 1st tag element. */
1117  xx = headerVerifyInfo(1, dl, pe, &entry->info, 0);
1118  if (xx != -1) {
1119  (void) snprintf(buf, sizeof(buf),
1120  _("tag[%d]: BAD, tag %u type %u offset %d count %u"),
1121  0, (unsigned) entry->info.tag, (unsigned) entry->info.type,
1122  (int)entry->info.offset, (unsigned) entry->info.count);
1123  goto exit;
1124  }
1125 
1126  /* Is there an immutable header region tag? */
1127 /*@-sizeoftype@*/
1128  if (entry->info.tag != RPMTAG_HEADERIMMUTABLE) {
1129  rc = RPMRC_NOTFOUND;
1130  goto exit;
1131  }
1132 
1133  /* Is the region tag sane? */
1134  if (!(entry->info.type == RPM_BIN_TYPE
1135  && entry->info.count == (rpmTagCount)REGION_TAG_COUNT))
1136  {
1137  (void) snprintf(buf, sizeof(buf),
1138  _("region tag: BAD, tag %u type %u offset %d count %u"),
1139  (unsigned) entry->info.tag, (unsigned) entry->info.type,
1140  (int)entry->info.offset, (unsigned) entry->info.count);
1141  goto exit;
1142  }
1143 /*@=sizeoftype@*/
1144 
1145  /* Is the offset within the data area? */
1146  if (entry->info.offset >= (int) dl) {
1147  (void) snprintf(buf, sizeof(buf),
1148  _("region offset: BAD, tag %u type %u offset %d count %u"),
1149  (unsigned) entry->info.tag, (unsigned) entry->info.type,
1150  (int)entry->info.offset, (unsigned) entry->info.count);
1151  goto exit;
1152  }
1153 
1154  /* Is there an immutable header region tag trailer? */
1155  regionEnd = dataStart + entry->info.offset;
1156 /*@-sizeoftype@*/
1157  (void) memcpy(info, regionEnd, REGION_TAG_COUNT);
1158  regionEnd += REGION_TAG_COUNT;
1159 
1160  xx = headerVerifyInfo(1, il * sizeof(*pe), info, &entry->info, 1);
1161  if (xx != -1 ||
1162  !(entry->info.tag == RPMTAG_HEADERIMMUTABLE
1163  && entry->info.type == REGION_TAG_TYPE
1164  && entry->info.count == (rpmTagCount)REGION_TAG_COUNT))
1165  {
1166  (void) snprintf(buf, sizeof(buf),
1167  _("region trailer: BAD, tag %u type %u offset %d count %u"),
1168  (unsigned) entry->info.tag, (unsigned) entry->info.type,
1169  (int)entry->info.offset, (unsigned) entry->info.count);
1170  goto exit;
1171  }
1172 /*@=sizeoftype@*/
1173  memset(info, 0, sizeof(*info));
1174 
1175  /* Is the no. of tags in the region less than the total no. of tags? */
1176  ril = (rpmuint32_t) (entry->info.offset/sizeof(*pe));
1177  if ((entry->info.offset % sizeof(*pe)) || ril > il) {
1178  (void) snprintf(buf, sizeof(buf),
1179  _("region size: BAD, ril(%u) > il(%u)"), (unsigned) ril, (unsigned)il);
1180  goto exit;
1181  }
1182 
1183  /* Find a header-only digest/signature tag. */
1184  for (i = ril; i < (unsigned) il; i++) {
1185  xx = headerVerifyInfo(1, dl, pe+i, &entry->info, 0);
1186  if (xx != -1) {
1187  (void) snprintf(buf, sizeof(buf),
1188  _("tag[%u]: BAD, tag %u type %u offset %d count %u"),
1189  (unsigned) i, (unsigned) entry->info.tag, (unsigned) entry->info.type,
1190  (int)entry->info.offset, (unsigned) entry->info.count);
1191  goto exit;
1192  }
1193 
1194  switch (entry->info.tag) {
1195  case RPMTAG_SHA1HEADER:
1196  { const unsigned char * b;
1197  if (vsflags & RPMVSF_NOSHA1HEADER)
1198  /*@switchbreak@*/ break;
1199  blen = 0;
1200  for (b = dataStart + entry->info.offset; *b != '\0'; b++) {
1201  if (strchr("0123456789abcdefABCDEF", *b) == NULL)
1202  /*@innerbreak@*/ break;
1203  blen++;
1204  }
1205  if (entry->info.type != RPM_STRING_TYPE || *b != '\0' || blen != 40)
1206  {
1207  (void) snprintf(buf, sizeof(buf), _("hdr SHA1: BAD, not hex"));
1208  goto exit;
1209  }
1210  if (info->tag == 0) {
1211  *info = entry->info; /* structure assignment */
1212  siglen = blen + 1;
1213  }
1214  } /*@switchbreak@*/ break;
1215  case RPMTAG_RSAHEADER:
1216  if (vsflags & RPMVSF_NORSAHEADER)
1217  /*@switchbreak@*/ break;
1218  if (entry->info.type != RPM_BIN_TYPE) {
1219  (void) snprintf(buf, sizeof(buf), _("hdr RSA: BAD, not binary"));
1220  goto exit;
1221  }
1222  *info = entry->info; /* structure assignment */
1223  siglen = info->count;
1224  /*@switchbreak@*/ break;
1225  case RPMTAG_DSAHEADER:
1226  if (vsflags & RPMVSF_NODSAHEADER)
1227  /*@switchbreak@*/ break;
1228  if (entry->info.type != RPM_BIN_TYPE) {
1229  (void) snprintf(buf, sizeof(buf), _("hdr DSA: BAD, not binary"));
1230  goto exit;
1231  }
1232  *info = entry->info; /* structure assignment */
1233  siglen = info->count;
1234  /*@switchbreak@*/ break;
1235  case RPMTAG_ECDSAHEADER:
1236  if (vsflags & RPMVSF_NOECDSAHEADER)
1237  /*@switchbreak@*/ break;
1238  if (entry->info.type != RPM_BIN_TYPE) {
1239  (void) snprintf(buf, sizeof(buf), _("hdr ECDSA: BAD, not binary"));
1240  goto exit;
1241  }
1242  *info = entry->info; /* structure assignment */
1243  siglen = info->count;
1244  /*@switchbreak@*/ break;
1245  default:
1246  /*@switchbreak@*/ break;
1247  }
1248  }
1249  rc = RPMRC_NOTFOUND;
1250 
1251 exit:
1252  /* Return determined RPMRC_OK/RPMRC_FAIL conditions. */
1253  if (rc != RPMRC_NOTFOUND) {
1254  buf[sizeof(buf)-1] = '\0';
1255  if (msg) *msg = xstrdup(buf);
1256 if (_pkgio_debug)
1257 fprintf(stderr, "<-- headerCheck #1: rc %d \"%s\"\n", rc, (msg ? *msg: ""));
1258  return rc;
1259  }
1260 
1261  /* If no header-only digest/signature, then do simple sanity check. */
1262  if (info->tag == 0) {
1263  xx = (ril > 0 ? headerVerifyInfo(ril-1, dl, pe+1, &entry->info, 0) : -1);
1264  if (xx != -1) {
1265  (void) snprintf(buf, sizeof(buf),
1266  _("tag[%d]: BAD, tag %u type %u offset %d count %u"),
1267  xx+1, (unsigned) entry->info.tag, (unsigned) entry->info.type,
1268  (int)entry->info.offset, (unsigned) entry->info.count);
1269  rc = RPMRC_FAIL;
1270  } else {
1271  (void) snprintf(buf, sizeof(buf), "Header sanity check: OK");
1272  rc = RPMRC_OK;
1273  }
1274  buf[sizeof(buf)-1] = '\0';
1275  if (msg) *msg = xstrdup(buf);
1276 if (_pkgio_debug)
1277 fprintf(stderr, "<-- headerCheck #2: rc %d \"%s\"\n", rc, (msg ? *msg: ""));
1278  return rc;
1279  }
1280 
1281  /* Verify header-only digest/signature. */
1282 assert(dig != NULL);
1283  dig->nbytes = 0;
1284 
1285  sig = memcpy(xmalloc(siglen), dataStart + info->offset, siglen);
1286  {
1287  const void * osig = pgpGetSig(dig);
1288 /*@-modobserver -observertrans -dependenttrans @*/ /* FIX: pgpSetSig() lazy free. */
1289  osig = _free(osig);
1290 /*@=modobserver =observertrans =dependenttrans @*/
1291  (void) pgpSetSig(dig, info->tag, info->type, sig, info->count);
1292  }
1293 
1294  /* Verify header signatures/digests. */
1295  switch (info->tag) {
1296  case RPMTAG_RSAHEADER:
1297  /* Parse the parameters from the OpenPGP packets that will be needed. */
1298  pleft = info->count;
1299  xx = pgpPktLen((const rpmuint8_t *)sig, pleft, pp);
1300  xx = rpmhkpLoadSignature(NULL, dig, pp);
1301  if (dig->signature.version != (rpmuint8_t)3
1302  && dig->signature.version != (rpmuint8_t)4)
1303  {
1305  _("skipping header with unverifiable V%u signature\n"),
1306  (unsigned) dig->signature.version);
1307  rc = RPMRC_FAIL;
1308  goto exit;
1309  }
1310 
1311  xx = hBlobDigest(uh, dig, dig->signature.hash_algo,
1312  regionEnd, ril, &dig->hrsa);
1313 
1314  break;
1315  case RPMTAG_DSAHEADER:
1316  /* Parse the parameters from the OpenPGP packets that will be needed. */
1317  pleft = info->count;
1318  xx = pgpPktLen((const rpmuint8_t *)sig, pleft, pp);
1319  xx = rpmhkpLoadSignature(NULL, dig, pp);
1320  if (dig->signature.version != (rpmuint8_t)3
1321  && dig->signature.version != (rpmuint8_t)4)
1322  {
1324  _("skipping header with unverifiable V%u signature\n"),
1325  (unsigned) dig->signature.version);
1326  rc = RPMRC_FAIL;
1327  goto exit;
1328  }
1329 
1330  xx = hBlobDigest(uh, dig, dig->signature.hash_algo,
1331  regionEnd, ril, &dig->hdsa);
1332 
1333  break;
1334  case RPMTAG_ECDSAHEADER:
1335  /* Parse the parameters from the OpenPGP packets that will be needed. */
1336  pleft = info->count;
1337  xx = pgpPktLen((const rpmuint8_t *)sig, pleft, pp);
1338  xx = rpmhkpLoadSignature(NULL, dig, pp);
1339  if (dig->signature.version != (rpmuint8_t)3
1340  && dig->signature.version != (rpmuint8_t)4)
1341  {
1343  _("skipping header with unverifiable V%u signature\n"),
1344  (unsigned) dig->signature.version);
1345  rc = RPMRC_FAIL;
1346  goto exit;
1347  }
1348 
1349  xx = hBlobDigest(uh, dig, dig->signature.hash_algo,
1350  regionEnd, ril, &dig->hecdsa);
1351 
1352  break;
1353  case RPMTAG_SHA1HEADER:
1354 
1355  /* XXX dig->hsha? */
1356  xx = hBlobDigest(uh, dig, PGPHASHALGO_SHA1,
1357  regionEnd, ril, &dig->hdsa);
1358 
1359  break;
1360  default:
1361  sig = _free(sig);
1362  break;
1363  }
1364 
1365  buf[0] = '\0';
1366  rc = rpmVerifySignature(dig, buf);
1367 
1368  buf[sizeof(buf)-1] = '\0';
1369  if (msg) *msg = xstrdup(buf);
1370 
1371 if (_pkgio_debug)
1372 fprintf(stderr, "<-- headerCheck #3: rc %d \"%s\"\n", rc, (msg ? *msg: ""));
1373  return rc;
1374 }
1375 
1381 static size_t szHeader(/*@null@*/ const void * ptr)
1382  /*@*/
1383 {
1384  rpmuint32_t p[4];
1385 assert(ptr != NULL);
1386  memcpy(p, ptr, sizeof(p));
1387  return (8 + 8 + 16 * ntohl(p[2]) + ntohl(p[3]));
1388 }
1389 
1390 /*@-globuse@*/
1398 static rpmRC ckHeader(/*@unused@*/ FD_t fd, const void * ptr,
1399  /*@unused@*/ /*@null@*/ const char ** msg)
1400  /*@globals fileSystem, internalState @*/
1401  /*@modifies ptr, fileSystem, internalState @*/
1402 {
1403  rpmRC rc = RPMRC_OK;
1404  Header h;
1405 
1406  h = headerLoad((void *)ptr);
1407  if (h == NULL)
1408  rc = RPMRC_FAIL;
1409  (void)headerFree(h);
1410  h = NULL;
1411 
1412  return rc;
1413 }
1414 
1422 static rpmRC rpmReadHeader(FD_t fd, /*@null@*/ Header * hdrp,
1423  /*@null@*/ const char ** msg)
1424  /*@globals fileSystem, internalState @*/
1425  /*@modifies fd, *hdrp, *msg, fileSystem, internalState @*/
1426 {
1427 rpmxar xar = fdGetXAR(fd);
1428  pgpDig dig = pgpDigLink(fdGetDig(fd));
1429  char buf[BUFSIZ];
1430  rpmuint32_t block[4];
1431  rpmuint32_t il;
1432  rpmuint32_t dl;
1433  rpmuint32_t * ei = NULL;
1434  size_t uc = 0;
1435  unsigned char * b;
1436  size_t startoff;
1437  size_t nb;
1438  Header h = NULL;
1439  const char * origin = NULL;
1440  rpmRC rc = RPMRC_FAIL; /* assume failure */
1441  int xx;
1442  static int map = 1;
1443 
1444 if (_pkgio_debug)
1445 fprintf(stderr, "--> rpmReadHeader(%p, %p, %p)\n", fd, hdrp, msg);
1446 
1447  /* Create (if not already) a signature parameters container. */
1448  if (dig == NULL) {
1450  (void) fdSetDig(fd, dig);
1451  }
1452 
1453  buf[0] = '\0';
1454 
1455  if (hdrp)
1456  *hdrp = NULL;
1457 
1458  memset(block, 0, sizeof(block));
1459  if (xar != NULL) {
1460  const char item[] = "Header";
1461  if ((xx = rpmxarNext(xar)) != 0 || (xx = rpmxarPull(xar, item)) != 0) {
1462  (void) snprintf(buf, sizeof(buf),
1463  _("XAR file not found (or no XAR support)"));
1464  rc = RPMRC_NOTFOUND;
1465  goto exit;
1466  }
1467  }
1468 
1469  startoff = fd->stats->ops[FDSTAT_READ].bytes;
1470  if ((xx = (int) timedRead(fd, (char *)block, sizeof(block))) != (int)sizeof(block)) {
1471  /* XXX Handle EOF's as RPMRC_NOTFOUND, not RPMRC_FAIL, returns. */
1472  if (xx == 0)
1473  rc = RPMRC_NOTFOUND;
1474  else
1475  (void) snprintf(buf, sizeof(buf),
1476  _("hdr size(%u): BAD, read returned %d"), (unsigned)sizeof(block), xx);
1477  goto exit;
1478  }
1479 
1480  b = NULL;
1481  nb = 0;
1482  (void) headerGetMagic(NULL, &b, &nb);
1483  if (memcmp(block, b, nb)) {
1484  unsigned char * x = (unsigned char *) block;
1485 /*@+charint@*/
1486  (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]);
1487 /*@=charint@*/
1488  goto exit;
1489  }
1490 
1491  il = (rpmuint32_t)ntohl(block[2]);
1492  if (hdrchkTags(il)) {
1493  (void) snprintf(buf, sizeof(buf),
1494  _("hdr tags: BAD, no. of tags(%u) out of range"), (unsigned) il);
1495 
1496  goto exit;
1497  }
1498  dl = (rpmuint32_t)ntohl(block[3]);
1499  if (hdrchkData(dl)) {
1500  (void) snprintf(buf, sizeof(buf),
1501  _("hdr data: BAD, no. of bytes(%u) out of range\n"), (unsigned) dl);
1502  goto exit;
1503  }
1504 
1505 /*@-sizeoftype@*/
1506  nb = (il * sizeof(struct entryInfo_s)) + dl;
1507 /*@=sizeoftype@*/
1508  uc = sizeof(il) + sizeof(dl) + nb;
1509  if (map) {
1510  static const int prot = PROT_READ | PROT_WRITE;
1511  static const int flags = MAP_PRIVATE| MAP_ANONYMOUS;
1512  static const int fdno = -1;
1513  static const off_t off = 0;
1514 
1515  ei = (rpmuint32_t *) mmap(NULL, uc, prot, flags, fdno, off);
1516 assert(ei != NULL && ei != (void *)-1); /* coverity #124081 */
1517  if (ei == NULL || ei == (void *)-1)
1518  fprintf(stderr,
1519  "==> mmap(%p[%u], 0x%x, 0x%x, %d, 0x%x) error(%d): %s\n",
1520  NULL, (unsigned)uc, prot, flags, fdno, (unsigned)off,
1521  errno, strerror(errno));
1522  } else {
1523  ei = (rpmuint32_t *) xmalloc(uc);
1524  }
1525 
1526  if ((xx = (int) timedRead(fd, (char *)&ei[2], nb)) != (int) nb) {
1527  (void) snprintf(buf, sizeof(buf),
1528  _("hdr blob(%u): BAD, read returned %d"), (unsigned)nb, xx);
1529  goto exit;
1530  }
1531  ei[0] = block[2];
1532  ei[1] = block[3];
1533 
1534  if (map) {
1535  if (mprotect(ei, uc, PROT_READ) != 0)
1536  fprintf(stderr, "==> mprotect(%p[%u],0x%x) error(%d): %s\n",
1537  ei, (unsigned)uc, PROT_READ,
1538  errno, strerror(errno));
1539  }
1540 
1541  /* Sanity check header tags */
1542  rc = headerCheck(dig, ei, uc, msg);
1543  if (rc != RPMRC_OK)
1544  goto exit;
1545 
1546  /* OK, blob looks sane, load the header. */
1547  h = headerLoad(ei);
1548  if (h == NULL) {
1549  (void) snprintf(buf, sizeof(buf), _("hdr load: BAD\n"));
1550  goto exit;
1551  }
1552  if (map) {
1553  h->flags |= HEADERFLAG_MAPPED;
1554  h->flags |= HEADERFLAG_RDONLY;
1555  } else
1557  ei = NULL; /* XXX will be freed with header */
1558 
1559  /* Save the opened path as the header origin. */
1560  /* XXX TODO: push the Realpath() underneath fdGetOPath(). */
1561  origin = fdGetOPath(fd);
1562  if (origin != NULL) {
1563  const char * lpath = NULL;
1564  int ut = urlPath(origin, &lpath);
1565  ut = ut; /* XXX keep gcc quiet. */
1566  if (lpath && *lpath != '/') {
1567  char * rpath = Realpath(origin, NULL);
1568  (void) headerSetOrigin(h, (rpath ? rpath : NULL));
1569  rpath = _free(rpath);
1570  } else
1571  (void) headerSetOrigin(h, origin);
1572  }
1573 /*@-mods@*/
1574  { struct stat * st = headerGetStatbuf(h);
1575  int saveno = errno;
1576  (void) Fstat(fd, st);
1577  errno = saveno;
1578  }
1579 /*@=mods@*/
1580  (void) headerSetStartOff(h, (rpmuint32_t)startoff);
1581  (void) headerSetEndOff(h, fd->stats->ops[FDSTAT_READ].bytes);
1582 
1583 exit:
1584  if (hdrp && h && rc == RPMRC_OK)
1585  *hdrp = headerLink(h);
1586  if (ei != NULL && uc > 0) {
1587  if (map) {
1588  if (munmap(ei, uc) != 0)
1589  fprintf(stderr, "==> munmap(%p[%u]) error(%d): %s\n",
1590  ei, (unsigned)uc, errno, strerror(errno));
1591  ei = NULL;
1592  } else
1593  ei = _free(ei);
1594  }
1595  dig = pgpDigFree(dig);
1596  (void)headerFree(h);
1597  h = NULL;
1598 
1599  if (msg != NULL && *msg == NULL && buf[0] != '\0') {
1600  buf[sizeof(buf)-1] = '\0';
1601  *msg = xstrdup(buf);
1602  }
1603 
1604 if (_pkgio_debug)
1605 fprintf(stderr, "<-- rpmReadHeader: rc %d \"%s\"\n", rc, (msg ? *msg: ""));
1606  return rc;
1607 }
1608 
1616 static rpmRC rdHeader(FD_t fd, /*@out@*/ /*@null@*/ void * ptr,
1617  /*@null@*/ const char ** msg)
1618  /*@globals fileSystem, internalState @*/
1619  /*@modifies fd, *ptr, *msg, fileSystem, internalState @*/
1620 {
1621  Header * hdrp = (Header *) ptr;
1622 /*@-compdef@*/
1623  return rpmReadHeader(fd, hdrp, msg);
1624 /*@=compdef@*/
1625 }
1626 
1634 static rpmRC wrHeader(FD_t fd, void * ptr,
1635  /*@unused@*/ /*@null@*/ const char ** msg)
1636  /*@globals fileSystem, internalState @*/
1637  /*@modifies fd, ptr, *msg, fileSystem, internalState @*/
1638 {
1639  Header h = (Header) ptr;
1640  return rpmWriteHeader(fd, h, msg);
1641 }
1642 /*@=globuse@*/
1643 
1644 /*===============================================*/
1645 
1646 size_t rpmpkgSizeof(const char * fn, const void * ptr)
1647 {
1648  size_t len = 0;
1649 
1650  if (!strcmp(fn, "Lead"))
1651  len = 96; /* RPMLEAD_SIZE */
1652  else
1653  if (!strcmp(fn, "Signature")) {
1654  len = szHeader(ptr);
1655  len += ((8 - (len % 8)) % 8); /* padding */
1656  } else
1657  if (!strcmp(fn, "Header"))
1658  len = szHeader(ptr);
1659  return len;
1660 }
1661 
1662 rpmRC rpmpkgCheck(const char * fn, FD_t fd, const void * ptr, const char ** msg)
1663 {
1664  rpmRC rc = RPMRC_FAIL;
1665 
1666  if (msg)
1667  *msg = NULL;
1668 
1669  if (!strcmp(fn, "Header"))
1670  rc = ckHeader(fd, ptr, msg);
1671  return rc;
1672 }
1673 
1674 rpmRC rpmpkgRead(const char * fn, FD_t fd, void * ptr, const char ** msg)
1675 {
1676  rpmRC rc = RPMRC_FAIL;
1677 
1678  if (msg)
1679  *msg = NULL;
1680 
1681  if (!strcmp(fn, "Lead"))
1682  rc = rdLead(fd, ptr, msg);
1683  else
1684  if (!strcmp(fn, "Signature"))
1685  rc = rdSignature(fd, ptr, msg);
1686  else
1687  if (!strcmp(fn, "Header"))
1688  rc = rdHeader(fd, ptr, msg);
1689  return rc;
1690 }
1691 
1692 rpmRC rpmpkgWrite(const char * fn, FD_t fd, void * ptr, const char ** msg)
1693 {
1694  rpmRC rc = RPMRC_FAIL;
1695 
1696  if (msg)
1697  *msg = NULL;
1698 
1699  if (!strcmp(fn, "Lead"))
1700  rc = wrLead(fd, ptr, msg);
1701  else
1702  if (!strcmp(fn, "Signature"))
1703  rc = wrSignature(fd, ptr, msg);
1704  else
1705  if (!strcmp(fn, "Header"))
1706  rc = wrHeader(fd, ptr, msg);
1707  return rc;
1708 }
Structure(s)and methods for a XAR archive wrapper format.
FDSTAT_t stats
const bson * b
Definition: bson.h:280
rpmTagType t
Definition: rpmtag.h:504
void _rpmhkpDumpDig(const char *msg, pgpDig dig, FILE *fp)
Definition: rpmhkp.c:1164
pgpDigParams pgpGetPubkey(pgpDig dig)
Return OpenPGP pubkey parameters.
Definition: rpmpgp.c:1397
rpmTag tag
Definition: rpmtag.h:503
const char ** argv
Definition: rpmtag.h:75
struct rpmxar_s * rpmxar
Definition: rpmxar.h:14
rpmtime_t rpmswExit(rpmop op, ssize_t rc)
Exit timed operation.
Definition: rpmsw.c:264
int pgpSetFindPubkey(pgpDig dig, int(*findPubkey)(void *ts, void *dig), void *_ts)
Set find pubkey vector.
Definition: rpmpgp.c:1450
int rpmhkpFindKey(rpmhkp hkp, pgpDig dig, const rpmuint8_t *signid, rpmuint8_t pubkey_algo)
Definition: rpmhkp.c:404
struct entryInfo_s info
rpmRC rpmhkpValidate(rpmhkp hkp, const char *keyname)
Retrieve/Validate binding and certification signatures on a pubkey.
Definition: rpmhkp.c:901
int headerVerifyInfo(rpmuint32_t il, rpmuint32_t dl, const void *pev, void *iv, int negate)
Perform simple sanity and range checks on header tag(s).
pgpDig pgpDigFree(pgpDig dig)
Destroy a container for parsed OpenPGP packates.
const char const char size_t len
Definition: bson.h:823
const char bson_timestamp_t * ts
Definition: bson.h:1004
static rpmRC wrHeader(FD_t fd, void *ptr, const char **msg)
Write metadata header.
Definition: pkgio.c:1634
rpmuint32_t headerSetStartOff(Header h, rpmuint32_t startoff)
Store header starting byte offset.
Definition: header.c:1295
int pgpPktLen(const rpmuint8_t *pkt, size_t pleft, pgpPkt pp)
Definition: rpmpgp.c:999
static size_t szHeader(const void *ptr)
Return size of Header.
Definition: pkgio.c:1381
static rpmRC rdSignature(FD_t fd, void *ptr, const char **msg)
Read (and verify header+payload size) signature header.
Definition: pkgio.c:750
static const int zero
Definition: bson.c:111
rpmRC rpmpkgWrite(const char *fn, FD_t fd, void *ptr, const char **msg)
Write item onto file descriptor.
Definition: pkgio.c:1692
const void * pgpGetSig(pgpDig dig)
Get signature tag data, i.e.
Definition: rpmpgp.c:1412
uint32_t rpmmiInstance(rpmmi mi)
Return header instance for current position of rpmdb iterator.
Definition: rpmdb.c:1747
size_t Fwrite(const void *buf, size_t size, size_t nmemb, FD_t fd)
fwrite(3) clone.
Definition: rpmio.c:2434
#define timedRead
Definition: pkgio.c:63
char * xstrdup(const char *str)
Definition: rpmmalloc.c:321
rpmuint32_t * ui32p
Definition: rpmtag.h:70
unsigned short type
Definition: pkgio.c:483
struct pgpDigParams_s * pgpDigParams
Definition: rpmiotypes.h:101
DIGEST_CTX rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags)
Initialize digest context.
Definition: digest.c:247
char * rpmGetPath(const char *path,...)
Return (malloc'ed) expanded, canonicalized, file path.
Definition: macro.c:3443
static const char * fdGetOPath(FD_t fd)
struct headerToken_s * Header
Definition: rpmtag.h:22
int headerGet(Header h, HE_t he, unsigned int flags)
Retrieve extension or tag value from a header.
Definition: header.c:2231
rpmTagType type
struct rpmbf_s * rpmbf
Definition: rpmbf.h:17
static unsigned int pgpGrab(const rpmuint8_t *s, size_t nbytes)
Return (native-endian) integer from big-endian representation.
Definition: rpmpgp.h:1036
enum pgpHashAlgo_e pgpHashAlgo
9.4.
rpmhkp rpmhkpNew(const rpmuint8_t *keyid, uint32_t flags)
Create a new hkp handle.
Definition: rpmhkp.c:112
The Header data structure.
static pgpDig fdGetDig(FD_t fd)
int rpmxarNext(rpmxar xar)
Iterate a xar archive instance.
Definition: rpmxar.c:128
rpmtime_t rpmswAdd(rpmop to, rpmop from)
Sum statistic counters.
Definition: rpmsw.c:280
int headerSetOrigin(Header h, const char *origin)
Store header origin (e.g path or URL).
Definition: header.c:1189
static rpmVSFlags vsflags
Definition: rpmcache.c:547
Definition: rpmdb.c:436
rpmRC headerCheck(pgpDig dig, const void *uh, size_t uc, const char **msg)
Check header consistency, performing headerGet() the hard way.
Definition: pkgio.c:1075
int errno
int pgpSetSig(pgpDig dig, rpmuint32_t sigtag, rpmuint32_t sigtype, const void *sig, rpmuint32_t siglen)
Set signature tag info, i.e.
Definition: rpmpgp.c:1422
enum rpmtsOpX_e rpmtsOpX
Indices for timestamps.
pgpDig pgpDigLink(pgpDig dig)
Reference a signature parameters instance.
#define HEADERFLAG_ALLOCATED
static void rpmlog(int code, const char *fmt,...)
Definition: rpmlog.h:299
#define HEADERFLAG_RDONLY
rpmhkp rpmhkpFree(rpmhkp hkp)
Destroy a hkp handle.
rpmRC rpmpkgCheck(const char *fn, FD_t fd, const void *ptr, const char **msg)
Verify item integrity.
Definition: pkgio.c:1662
pgpDigParams rpmtsPubkey(const rpmts ts)
Return OpenPGP pubkey constants.
Definition: pkgio.c:144
#define REGION_TAG_TYPE
void * headerUnload(Header h, size_t *lenp)
headerUnload.
Definition: header.c:648
rpmmi rpmmiInit(rpmdb db, rpmTag tag, const void *keyp, size_t keylen)
Return database iterator.
Definition: rpmdb.c:2495
rpmTagCount count
int Fstat(FD_t fd, struct stat *st)
fstat(2) clone.
Definition: rpmrpc.c:1441
char * alloca()
static rpmRC rpmWriteHeader(FD_t fd, Header h, const char **msg)
Write (with unload) header to file handle.
Definition: pkgio.c:75
pgpArmor pgpReadPkts(const char *fn, rpmuint8_t **pkt, size_t *pktlen)
Parse armored OpenPGP packets from a file.
Definition: rpmpgp.c:1739
unsigned int rpmuint32_t
Definition: rpmiotypes.h:28
struct _HE_s * HE_t
Definition: rpmtag.h:59
pgpVSFlags pgpDigVSFlags
Disabler bits(s) for signature/digest checking.
Definition: rpmpgp.c:1153
const char * Fstrerror(FD_t fd)
strerror(3) clone.
Definition: rpmio.c:2401
void * xcalloc(size_t nmemb, size_t size)
Definition: rpmmalloc.c:300
void * ptr
Definition: rpmtag.h:67
int rpmDigestUpdate(DIGEST_CTX ctx, const void *data, size_t len)
Update context with next plain text buffer.
Definition: digest.c:986
rpmbf rpmbfFree(rpmbf bf)
Destroy a Bloom filter.
static const char * _pgpPubkeyAlgo2Name(uint32_t algo)
Definition: rpmpgp.h:1191
static void fdSetDig(FD_t fd, pgpDig dig)
int rpmxarPull(rpmxar xar, const char *fn)
Definition: rpmxar.c:168
rpmop rpmtsOp(rpmts ts, rpmtsOpX opx)
Retrieve operation timestamp from a transaction set.
Definition: pkgio.c:133
void rpmtsCleanDig(rpmts ts)
Free signature verification data.
Definition: pkgio.c:456
static rpmRC wrLead(FD_t fd, const void *ptr, const char **msg)
Write lead to file handle.
Definition: pkgio.c:508
struct entryInfo_s * entryInfo
Description of tag data.
size_t rpmpkgSizeof(const char *fn, const void *ptr)
Return size of item in bytes.
Definition: pkgio.c:1646
unsigned char rpmuint8_t
Private int typedefs to avoid C99 portability issues.
Definition: rpmiotypes.h:26
The lead data structure.
Definition: pkgio.c:479
static rpmRC rdHeader(FD_t fd, void *ptr, const char **msg)
Read metadata header.
Definition: pkgio.c:1616
rpmTagData p
Definition: rpmtag.h:506
static rpmRC rpmReadHeader(FD_t fd, Header *hdrp, const char **msg)
Return checked and loaded header.
Definition: pkgio.c:1422
unsigned short osnum
Definition: pkgio.c:486
struct stat * headerGetStatbuf(Header h)
Return header stat(2) buffer (of origin *.rpm file).
Definition: header.c:1228
struct pgpPkt_s * pgpPkt
Definition: rpmiotypes.h:93
rpmuint32_t headerSetEndOff(Header h, rpmuint32_t endoff)
Store header ending byte offset.
Definition: header.c:1307
pgpDigParams pgpGetSignature(pgpDig dig)
Return OpenPGP signature parameters.
Definition: rpmpgp.c:1392
static int hBlobDigest(const void *uh, pgpDig dig, pgpHashAlgo hash_algo, const unsigned char *regionEnd, rpmuint32_t ril, DIGEST_CTX *ctxp)
Definition: pkgio.c:1013
int rpmdbOpen(const char *prefix, rpmdb *dbp, int mode, mode_t perms)
Open rpm database.
Definition: rpmdb.c:1179
static void fdSetXAR(FD_t fd, rpmxar xar)
#define hdrchkTags(_ntags)
Sanity check on no.
unsigned short signature_type
Definition: pkgio.c:487
Digest private data.
Definition: digest.c:130
Header headerLoad(void *uh)
Convert header to in-memory representation.
Definition: header.c:970
The FD_t File Handle data structure.
struct pgpDig_s * pgpDig
Definition: rpmiotypes.h:97
struct rpmdb_s * rpmdb
Database of headers and tag value indices.
Definition: rpmtypes.h:43
#define HEADERFLAG_SIGNATURE
rpmTagCount c
Definition: rpmtag.h:507
Generate and verify rpm package signatures.
pgpVSFlags rpmVSFlags
Bit(s) to control digest and signature verification.
Definition: rpmts.h:35
Header headerFree(Header h)
Dereference a header instance.
int headerGetMagic(Header h, unsigned char **magicp, size_t *nmagicp)
Return header magic.
Definition: header.c:1162
rpmRC rpmVerifySignature(void *_dig, char *result)
Verify a signature from a package.
Definition: signature.c:1094
int rpmswEnter(rpmop op, ssize_t rc)
Enter timed operation.
Definition: rpmsw.c:248
const char const bson const bson * op
Definition: mongo.h:505
struct rpmop_s * rpmop
Definition: rpmsw.h:24
char * rpmExpand(const char *arg,...)
Return (malloc'ed) concatenated macro expansion(s).
Definition: macro.c:3250
#define HEADERFLAG_MAPPED
static rpmRC ckHeader(FD_t fd, const void *ptr, const char **msg)
Check metadata header.
Definition: pkgio.c:1398
unsigned char major
Definition: pkgio.c:481
rpmmi rpmmiFree(rpmmi mi)
Destroy rpm database iterator.
Cumulative statistics for an operation.
Definition: rpmsw.h:39
rpmiob rpmiobNew(size_t len)
Create an I/O buffer.
Definition: rpmiob.c:44
const char const bson int mongo_write_concern int flags
Definition: mongo.h:485
Header headerLink(Header h)
Reference a header instance.
int pgpGrabPkts(const rpmuint8_t *pkts, size_t pktlen, rpmuint8_t ***pppkts, int *pnpkts)
Return array of packet pointers.
Definition: rpmpgp.c:1472
enum pgpPubkeyAlgo_e pgpPubkeyAlgo
9.1.
int _rpmhkp_debug
Definition: rpmhkp.c:19
rpmdb rpmtsGetRdb(rpmts ts)
Get transaction set database handle.
Definition: pkgio.c:151
enum rpmRC_e rpmRC
RPM return codes.
pgpDig pgpDigNew(pgpVSFlags vsflags, pgpPubkeyAlgo pubkey_algo)
Create a container for parsed OpenPGP packates.
Definition: rpmpgp.c:1314
size_t headerSizeof(Header h)
Return size of on-disk header representation in bytes.
Definition: header.c:266
rpmhkp rpmhkpLink(rpmhkp hkp)
Reference a hkp handle instance.
int rpmint32_t
Definition: rpmiotypes.h:33
int Ferror(FD_t fd)
ferror(3) clone.
Definition: rpmio.c:2951
Definition: rpmtag.h:502
const char const int i
Definition: bson.h:778
rpmRC rpmkuFindPubkey(pgpDigParams sigp, rpmiob *iobp)
Lookup pubkey in keyutils keyring.
Definition: rpmku.c:157
urltype urlPath(const char *url, const char **pathp)
Return path component of URL.
Definition: url.c:430
static unsigned char lead_magic[]
Definition: pkgio.c:494
static int snprintf(char *buf, int nb, const char *fmt,...)
Definition: rpmps.c:220
#define REGION_TAG_COUNT
Methods to handle package elements.
int pgpPubkeyFingerprint(const rpmuint8_t *pkt, size_t pktlen, rpmuint8_t *keyid)
Print/parse an OpenPGP subtype packet.
Definition: rpmpgp.c:1029
unsigned char magic[4]
Definition: pkgio.c:480
int rpmxarSwapBuf(rpmxar xar, unsigned char *b, size_t bsize, unsigned char **obp, size_t *obsizep)
Definition: rpmxar.c:203
struct rpmts_s * rpmts
The RPM Transaction Set.
Definition: rpmtypes.h:14
pgpDig rpmtsDig(rpmts ts)
Get OpenPGP packet parameters, i.e.
Definition: pkgio.c:441
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:756
struct rpmiob_s * rpmiob
Definition: rpmiotypes.h:60
Structures and prototypes used for an "rpmts" transaction set.
Header rpmmiNext(rpmmi mi)
Return next package header from iteration.
Definition: rpmdb.c:2252
static rpmxar fdGetXAR(FD_t fd)
rpmRC rpmtsFindPubkey(rpmts ts, void *_dig)
Retrieve pubkey from rpm database.
Definition: pkgio.c:162
int _pkgio_debug
Definition: pkgio.c:55
static rpmRC wrSignature(FD_t fd, void *ptr, const char **msg)
Write signature header.
Definition: pkgio.c:673
int rpmbfAdd(rpmbf bf, const void *_s, size_t ns)
Add item to a Bloom filter.
Definition: rpmbf.c:68
rpmuint32_t flags
rpmbf rpmbfLink(rpmbf bf)
Reference a Bloom filter instance.
int Fileno(FD_t fd)
fileno(3) clone.
Definition: rpmio.c:2998
struct indexEntry_s * indexEntry
A single tag from a Header.
#define hdrchkData(_nbytes)
Sanity check on data size and/or offset and/or count.
rpmxar rpmxarFree(rpmxar xar, const char *msg)
Destroy a xar archive instance.
#define _(Text)
Definition: system.h:29
rpmint32_t offset
char name[66]
Definition: pkgio.c:485
#define xmalloc
Definition: system.h:32
struct rpmhkp_s * rpmhkp
Definition: rpmhkp.h:11
rpmRC rpmpkgRead(const char *fn, FD_t fd, void *ptr, const char **msg)
Read item from file descriptor.
Definition: pkgio.c:1674
unsigned char minor
Definition: pkgio.c:482
Access RPM indices using Berkeley DB interface(s).
enum rpmTag_e rpmTag
Definition: rpmtag.h:470
#define D_(Text)
Definition: system.h:526
static char * pgpHexStr(const rpmuint8_t *p, size_t plen)
Return hex formatted representation of bytes.
Definition: rpmpgp.h:1124
unsigned short archnum
Definition: pkgio.c:484
static rpmRC printSize(FD_t fd, size_t siglen, size_t pad, size_t datalen)
Print package size.
Definition: pkgio.c:710
static rpmRC rdLead(FD_t fd, void *ptr, const char **msg)
Read lead from file handle.
Definition: pkgio.c:546
void * pgpStatsAccumulator(pgpDig dig, int opx)
Return pgpDig container accumulator structure.
Definition: rpmpgp.c:1436
char reserved[16]
Definition: pkgio.c:489
rpmxar rpmxarNew(const char *fn, const char *fmode)
Create a xar archive instance.
Definition: rpmxar.c:112
char * Realpath(const char *path, char *resolved_path)
realpath(3) clone.
Definition: rpmrpc.c:2330
rpmRC rpmkuStorePubkey(pgpDigParams sigp, rpmiob iob)
Store pubkey in keyutils keyring.
Definition: rpmku.c:204
int rpmhkpLoadSignature(rpmhkp hkp, pgpDig dig, pgpPkt pp)
Definition: rpmhkp.c:461
rpmuint32_t rpmTagCount
Definition: rpmtag.h:55
int rpmbfChk(rpmbf bf, const void *_s, size_t ns)
Check for item in a Bloom filter.
Definition: rpmbf.c:90