rpm  5.4.10
package.c
Go to the documentation of this file.
1 
5 #include "system.h"
6 
7 #include <netinet/in.h>
8 
9 #include <rpmio_internal.h>
10 #include <rpmcb.h> /* XXX fnpyKey */
11 
12 #define _RPMHKP_INTERNAL /* XXX internal prototypes. */
13 #include <rpmhkp.h>
14 
15 #include <rpmtag.h>
16 #include <rpmtypes.h>
17 #include <pkgio.h>
18 #include "signature.h" /* XXX rpmVerifySignature */
19 
20 #include "rpmts.h"
21 
22 #define _RPMEVR_INTERNAL
23 #include <rpmevr.h>
24 #include "debug.h"
25 
26 #define alloca_strdup(_s) strcpy(alloca(strlen(_s)+1), (_s))
27 
28 /*@access pgpDig @*/
29 /*@access pgpDigParams @*/
30 /*@access Header @*/ /* XXX compared with NULL */
31 /*@access FD_t @*/ /* XXX void * */
32 
33 /*@unchecked@*/ /*@only@*/ /*@null@*/
34 unsigned int * keyids = NULL;
35 
36 #ifndef DYING
37 /*@unchecked@*/
38 static unsigned int nkeyids_max = 256;
39 /*@unchecked@*/
40 static unsigned int nkeyids = 0;
41 /*@unchecked@*/
42 static unsigned int nextkeyid = 0;
43 
49 static int pgpStashKeyid(pgpDig dig)
50  /*@globals nextkeyid, nkeyids, keyids @*/
51  /*@modifies nextkeyid, nkeyids, keyids @*/
52 {
53  pgpDigParams sigp = pgpGetSignature(dig);
54  const void * sig = pgpGetSig(dig);
55  unsigned int keyid;
56  unsigned int i;
57 
58  if (sig == NULL || dig == NULL || sigp == NULL)
59  return 0;
60 
61  keyid = pgpGrab(sigp->signid+4, 4);
62  if (keyid == 0)
63  return 0;
64 
65  if (keyids != NULL)
66  for (i = 0; i < nkeyids; i++) {
67  if (keyid == keyids[i])
68  return 1;
69  }
70 
71  if (nkeyids < nkeyids_max) {
72  nkeyids++;
73  keyids = (unsigned int *) xrealloc(keyids, nkeyids * sizeof(*keyids));
74  }
75  if (keyids) /* XXX can't happen */
76  keyids[nextkeyid] = keyid;
77  nextkeyid++;
79 
80  return 0;
81 }
82 #endif
83 
84 /*@-boundsread@*/
85 static int dncmp(const void * a, const void * b)
86  /*@*/
87 {
88  const char *const * first = a;
89  const char *const * second = b;
90  return strcmp(*first, *second);
91 }
92 /*@=boundsread@*/
93 
94 /*@-bounds@*/
99 static void compressFilelist(Header h)
100  /*@modifies h @*/
101 {
102  HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
103 
104  char ** fileNames;
105  const char ** dirNames;
106  const char ** baseNames;
107  int32_t * dirIndexes;
108  rpmTagType fnt;
109  int count;
110  int i, xx;
111  int dirIndex = -1;
112 
113  /*
114  * This assumes the file list is already sorted, and begins with a
115  * single '/'. That assumption isn't critical, but it makes things go
116  * a bit faster.
117  */
118 
119  if (headerIsEntry(h, RPMTAG_DIRNAMES)) {
120  he->tag = RPMTAG_OLDFILENAMES;
121  headerDel(h, he, 0);
122  return; /* Already converted. */
123  }
124 
125  he->tag = RPMTAG_OLDFILENAMES;
126  if (!headerGet(h, he, 0))
127  return;
128 
129  fileNames = he->p.ptr;
130  if (he->c <= 0)
131  return;
132  count = he->c;
133 
134  dirNames = alloca(sizeof(*dirNames) * count); /* worst case */
135  baseNames = alloca(sizeof(*dirNames) * count);
136  dirIndexes = alloca(sizeof(*dirIndexes) * count);
137 
138  if (fileNames[0][0] != '/') {
139  /* HACK. Source RPM, so just do things differently */
140  dirIndex = 0;
141  dirNames[dirIndex] = "";
142  for (i = 0; i < count; i++) {
143  dirIndexes[i] = dirIndex;
144  baseNames[i] = fileNames[i];
145  }
146  goto exit;
147  }
148 
149  /*@-branchstate@*/
150  for (i = 0; i < count; i++) {
151  const char ** needle;
152  char savechar;
153  char * baseName;
154  int len;
155 
156  if (fileNames[i] == NULL) /* XXX can't happen */
157  continue;
158  baseName = strrchr(fileNames[i], '/') + 1;
159  len = baseName - fileNames[i];
160  needle = dirNames;
161  savechar = *baseName;
162  *baseName = '\0';
163 /*@-compdef@*/
164  if (dirIndex < 0 ||
165  (needle = bsearch(&fileNames[i], dirNames, dirIndex + 1, sizeof(dirNames[0]), dncmp)) == NULL) {
166  char *s = alloca(len + 1);
167  memcpy(s, fileNames[i], len + 1);
168  s[len] = '\0';
169  dirIndexes[i] = ++dirIndex;
170  dirNames[dirIndex] = s;
171  } else
172  dirIndexes[i] = needle - dirNames;
173 /*@=compdef@*/
174 
175  *baseName = savechar;
176  baseNames[i] = baseName;
177  }
178  /*@=branchstate@*/
179 
180 exit:
181  if (count > 0) {
182 
183  he->tag = RPMTAG_DIRINDEXES;
184  if (headerGet(h, he, 0))
185  dirIndexes = he->p.ptr;
186  he->tag = RPMTAG_BASENAMES;
187  if (headerGet(h, he, 0))
188  baseNames = he->p.ptr;
189  he->tag = RPMTAG_DIRNAMES;
190  if (headerGet(h, he, 0))
191  dirNames = he->p.ptr;
192 
193  he->tag = RPMTAG_DIRINDEXES;
194  he->t = RPM_UINT32_TYPE;
195  he->p.ptr = dirIndexes;
196  he->c = count;
197  headerPut(h, he, 0);
198 
199  he->tag = RPMTAG_BASENAMES;
200  he->t = RPM_STRING_ARRAY_TYPE;
201  he->p.ptr = baseNames;
202  he->c = count;
203  headerPut(h, he, 0);
204 
205  he->tag = RPMTAG_DIRNAMES;
206  he->t = RPM_STRING_ARRAY_TYPE;
207  he->p.ptr = dirNames;
208  he->c = dirIndex +1;
209  headerPut(h,he,0);
210  }
211 
212  fileNames = _free(fileNames);
213 
214  he->tag = RPMTAG_OLDFILENAMES;
215  headerDel(h, he, 0);
216 
217 }
218 /*@=bounds@*/
219 
220 /* copied verbatim from build/pack.c */
221 static void providePackageNVR(Header h)
222 {
223  HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
224  const char *N, *V, *R;
225 #ifdef RPM_VENDOR_MANDRIVA
226  const char *D;
227  int gotD;
228 #endif
229  rpmuint32_t E;
230  int gotE;
231  const char *pEVR;
232  char *p;
233  rpmuint32_t pFlags = RPMSENSE_EQUAL;
234  const char ** provides = NULL;
235  const char ** providesEVR = NULL;
236  rpmuint32_t * provideFlags = NULL;
237  int providesCount;
238  int bingo = 1;
239  size_t nb;
240  int xx;
241  int i;
242 
243  /* Generate provides for this package N-V-R. */
244  xx = headerNEVRA(h, &N, NULL, &V, &R, NULL);
245  if (!(N && V && R))
246  return;
247 
248  nb = 21 + strlen(V) + 1 + strlen(R) + 1;
249 #ifdef RPM_VENDOR_MANDRIVA
250  he->tag = RPMTAG_DISTEPOCH;
251  gotD = headerGet(h, he, 0);
252  D = (he->p.str ? he->p.str : NULL);
253  nb += (gotD ? strlen(D) + 1 : 0);
254 #endif
255  pEVR = p = alloca(nb);
256  *p = '\0';
257  he->tag = RPMTAG_EPOCH;
258  gotE = headerGet(h, he, 0);
259  E = (he->p.ui32p ? he->p.ui32p[0] : 0);
260  he->p.ptr = _free(he->p.ptr);
261  if (gotE) {
262  sprintf(p, "%d:", E);
263  p += strlen(p);
264  }
265  p = stpcpy( stpcpy( stpcpy(p, V) , "-") , R);
266 #ifdef RPM_VENDOR_MANDRIVA
267  if (gotD) {
268  p = stpcpy( stpcpy( p, ":"), D);
269  D = _free(D);
270  //(void) rpmlibNeedsFeature(h, "DistEpoch", "5.4.7-1");
271  }
272 #endif
273  V = _free(V);
274  R = _free(R);
275 
276  /*
277  * Rpm prior to 3.0.3 does not have versioned provides.
278  * If no provides at all are available, we can just add.
279  */
280  he->tag = RPMTAG_PROVIDENAME;
281 /*@-nullstate@*/
282  xx = headerGet(h, he, 0);
283 /*@=nullstate@*/
284  provides = he->p.argv;
285  providesCount = he->c;
286  if (!xx)
287  goto exit;
288 
289  /*
290  * Otherwise, fill in entries on legacy packages.
291  */
293 /*@-nullstate@*/
294  xx = headerGet(h, he, 0);
295 /*@=nullstate@*/
296  providesEVR = he->p.argv;
297  if (!xx) {
298  for (i = 0; i < providesCount; i++) {
299  /*@observer@*/
300  static const char * vdummy = "";
301  static rpmsenseFlags fdummy = RPMSENSE_ANY;
302 
304  he->t = RPM_STRING_ARRAY_TYPE;
305  he->p.argv = &vdummy;
306  he->c = 1;
307  he->append = 1;
308 /*@-nullstate@*/
309  xx = headerPut(h, he, 0);
310 /*@=nullstate@*/
311  he->append = 0;
312 
313  he->tag = RPMTAG_PROVIDEFLAGS;
314  he->t = RPM_UINT32_TYPE;
315  he->p.ui32p = (void *) &fdummy;
316  he->c = 1;
317  he->append = 1;
318 /*@-nullstate@*/
319  xx = headerPut(h, he, 0);
320 /*@=nullstate@*/
321  he->append = 0;
322  }
323  goto exit;
324  }
325 
326  he->tag = RPMTAG_PROVIDEFLAGS;
327 /*@-nullstate@*/
328  xx = headerGet(h, he, 0);
329 /*@=nullstate@*/
330  provideFlags = he->p.ui32p;
331 
332  /*@-nullderef@*/ /* LCL: providesEVR is not NULL */
333  if (provides && providesEVR && provideFlags)
334  for (i = 0; i < providesCount; i++) {
335  if (!(provides[i] && providesEVR[i]))
336  continue;
337  if (!(provideFlags[i] == RPMSENSE_EQUAL &&
338  !strcmp(N, provides[i]) && !strcmp(pEVR, providesEVR[i])))
339  continue;
340  bingo = 0;
341  break;
342  }
343  /*@=nullderef@*/
344 
345 exit:
346 /*@-usereleased@*/
347  provides = _free(provides);
348  providesEVR = _free(providesEVR);
349  provideFlags = _free(provideFlags);
350 /*@=usereleased@*/
351 
352  if (bingo) {
353  he->tag = RPMTAG_PROVIDENAME;
354  he->t = RPM_STRING_ARRAY_TYPE;
355  he->p.argv = &N;
356  he->c = 1;
357  he->append = 1;
358 /*@-nullstate@*/
359  xx = headerPut(h, he, 0);
360 /*@=nullstate@*/
361  he->append = 0;
362 
363  /* XXX succeeds only at allocating the necessary appended space,
364  * not copying to it..? */
365  xx = headerGet(h, he, 0);
366  he->p.argv[providesCount] = N;
367  xx = headerPut(h, he, 0);
368  _free(he->p.ptr);
369 
371  he->t = RPM_STRING_ARRAY_TYPE;
372  he->p.argv = &pEVR;
373  he->c = 1;
374  he->append = 1;
375 /*@-nullstate@*/
376  xx = headerPut(h, he, 0);
377 /*@=nullstate@*/
378  he->append = 0;
379 
380  he->tag = RPMTAG_PROVIDEFLAGS;
381  he->t = RPM_UINT32_TYPE;
382  he->p.ui32p = &pFlags;
383  he->c = 1;
384  he->append = 1;
385 /*@-nullstate@*/
386  xx = headerPut(h, he, 0);
387 /*@=nullstate@*/
388  he->append = 0;
389  }
390  N = _free(N);
391 }
392 
394 {
396  /* we have no way to know if this is a srpm or an rpm with no SOURCERPM */
397  /* but since this is an old v3 rpm, we suppose it's not a srpm */
398  HE_t he = (HE_t)memset(alloca(sizeof(*he)), 0, sizeof(*he));
399 
400  he->tag = RPMTAG_SOURCERPM;
401  he->t = RPM_STRING_TYPE;
402  he->p.str = "\0";
403  he->c = 1;
404  headerPut(h, he, 0);
405  }
406 }
407 
408 /* rpm v3 compatibility */
409 static void rpm3to4(Header h) {
410  const char * rpmversion = NULL;
411  HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
412 
413  he->tag = RPMTAG_RPMVERSION;
414  if (headerGet(h, he, 0)) {
415  rpmversion = he->p.str;
416  }
417 
418  if ((!rpmversion) || rpmversion[0] < '4') {
421  compressFilelist(h);
422  }
423  rpmversion = _free(rpmversion);
424  return;
425 }
426 
427 /*@-mods@*/
428 rpmRC rpmReadPackageFile(rpmts ts, FD_t fd, const char * fn, Header * hdrp)
429 {
430  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
431  HE_t she = (HE_t) memset(alloca(sizeof(*she)), 0, sizeof(*she));
432  pgpDig dig = rpmtsDig(ts);
433  char buf[8*BUFSIZ];
434  ssize_t count;
435  Header sigh = NULL;
436  rpmtsOpX opx;
437  rpmop op = NULL;
438  size_t nb;
439  unsigned ix;
440  Header h = NULL;
441  const char * msg = NULL;
443  rpmRC rc = RPMRC_FAIL; /* assume failure */
444  rpmop opsave = (rpmop) memset(alloca(sizeof(*opsave)), 0, sizeof(*opsave));
445  int xx;
446 pgpPkt pp = (pgpPkt) alloca(sizeof(*pp));
447 
448  if (hdrp) *hdrp = NULL;
449 
450 assert(dig != NULL);
451  (void) fdSetDig(fd, dig);
452 
453  /* Snapshot current I/O counters (cached persistent I/O reuses counters) */
454  (void) rpmswAdd(opsave, fdstat_op(fd, FDSTAT_READ));
455 
456  { const char item[] = "Lead";
457  msg = NULL;
458  rc = rpmpkgRead(item, fd, NULL, &msg);
459  switch (rc) {
460  default:
461  rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item, msg);
462  /*@fallthrough@*/
463  case RPMRC_NOTFOUND:
464  msg = _free(msg);
465  goto exit;
466  /*@notreached@*/ break;
467  case RPMRC_OK:
468  break;
469  }
470  msg = _free(msg);
471  }
472 
473  { const char item[] = "Signature";
474  msg = NULL;
475  rc = rpmpkgRead(item, fd, &sigh, &msg);
476  switch (rc) {
477  default:
478  rpmlog(RPMLOG_ERR, "%s: %s: %s", fn, item,
479  (msg && *msg ? msg : _("read failed\n")));
480  msg = _free(msg);
481  goto exit;
482  /*@notreached@*/ break;
483  case RPMRC_OK:
484  if (sigh == NULL) {
485  rpmlog(RPMLOG_ERR, _("%s: No signature available\n"), fn);
486  rc = RPMRC_FAIL;
487  goto exit;
488  }
489  break;
490  }
491  msg = _free(msg);
492  }
493 
494 #define _chk(_mask) (she->tag == 0 && !(vsflags & (_mask)))
495 
496  /*
497  * Figger the most effective available signature.
498  * Prefer signatures over digests, then header-only over header+payload.
499  * DSA will be preferred over RSA if both exist because tested first.
500  * Note that NEEDPAYLOAD prevents header+payload signatures and digests.
501  */
502  she->tag = (rpmTag)0;
503  opx = (rpmtsOpX)0;
504  vsflags = pgpDigVSFlags;
506  she->tag = (rpmTag)RPMSIGTAG_DSA;
507  } else
509  she->tag = (rpmTag)RPMSIGTAG_RSA;
510  } else
512  she->tag = (rpmTag)RPMSIGTAG_SHA1;
513  } else
516  {
517  she->tag = (rpmTag)RPMSIGTAG_MD5;
519  opx = RPMTS_OP_DIGEST;
520  }
521 
522  /* Read the metadata, computing digest(s) on the fly. */
523  h = NULL;
524  msg = NULL;
525 
526  /* XXX stats will include header i/o and setup overhead. */
527  /* XXX repackaged packages have appended tags, legacy dig/sig check fails */
528  if (opx > 0) {
529  op = (rpmop) pgpStatsAccumulator(dig, opx);
530  (void) rpmswEnter(op, 0);
531  }
532 /*@-type@*/ /* XXX arrow access of non-pointer (FDSTAT_t) */
533  nb = fd->stats->ops[FDSTAT_READ].bytes;
534  { const char item[] = "Header";
535  msg = NULL;
536  rc = rpmpkgRead(item, fd, &h, &msg);
537  if (rc != RPMRC_OK) {
538  rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item, msg);
539  msg = _free(msg);
540  goto exit;
541  }
542  msg = _free(msg);
543  }
544  nb = fd->stats->ops[FDSTAT_READ].bytes - nb;
545 /*@=type@*/
546  if (opx > 0 && op != NULL) {
547  (void) rpmswExit(op, nb);
548  op = NULL;
549  }
550 
551  /* Any digests or signatures to check? */
552  if (she->tag == 0) {
553  rc = RPMRC_OK;
554  goto exit;
555  }
556 
557  dig->nbytes = 0;
558 
559  /* Fish out the autosign pubkey (if present). */
560  he->tag = RPMTAG_PUBKEYS;
561  xx = headerGet(h, he, 0);
562  if (xx && he->p.argv != NULL && he->c > 0)
563  switch (he->t) {
564  default:
565  break;
567  ix = he->c - 1; /* XXX FIXME: assumes last pubkey */
568  dig->pub = _free(dig->pub);
569  dig->publen = 0;
570  { rpmiob iob = rpmiobNew(0);
571  iob = rpmiobAppend(iob, he->p.argv[ix], 0);
572  xx = pgpArmorUnwrap(iob, (rpmuint8_t **)&dig->pub, &dig->publen);
573  iob = rpmiobFree(iob);
574  }
575  if (xx != PGPARMOR_PUBKEY) {
576  dig->pub = _free(dig->pub);
577  dig->publen = 0;
578  }
579  break;
580  }
581  he->p.ptr = _free(he->p.ptr);
582 
583  /* Retrieve the tag parameters from the signature header. */
584  xx = headerGet(sigh, she, 0);
585  if (she->p.ptr == NULL) {
586  rc = RPMRC_FAIL;
587  goto exit;
588  }
589 /*@-ownedtrans -noeffect@*/
590  xx = pgpSetSig(dig, she->tag, she->t, she->p.ptr, she->c);
591 /*@=ownedtrans =noeffect@*/
592 
593  switch ((rpmSigTag)she->tag) {
594  default: /* XXX keep gcc quiet. */
595 assert(0);
596  /*@notreached@*/ break;
597  case RPMSIGTAG_RSA:
598  /* Parse the parameters from the OpenPGP packets that will be needed. */
599  xx = pgpPktLen(she->p.ui8p, she->c, pp);
600  xx = rpmhkpLoadSignature(NULL, dig, pp);
601  if (dig->signature.version != 3 && dig->signature.version != 4) {
603  _("skipping package %s with unverifiable V%u signature\n"),
604  fn, dig->signature.version);
605  rc = RPMRC_FAIL;
606  goto exit;
607  }
608  { void * uh = NULL;
609  rpmTagType uht;
610  rpmTagCount uhc;
611  unsigned char * hmagic = NULL;
612  size_t nmagic = 0;
613 
615  xx = headerGet(h, he, 0);
616  uht = he->t;
617  uh = he->p.ptr;
618  uhc = he->c;
619  if (!xx)
620  break;
621  (void) headerGetMagic(NULL, &hmagic, &nmagic);
622  op = (rpmop) pgpStatsAccumulator(dig, 10); /* RPMTS_OP_DIGEST */
623  (void) rpmswEnter(op, 0);
624  dig->hdrctx = rpmDigestInit((pgpHashAlgo)dig->signature.hash_algo, RPMDIGEST_NONE);
625  if (hmagic && nmagic > 0) {
626  (void) rpmDigestUpdate(dig->hdrctx, hmagic, nmagic);
627  dig->nbytes += nmagic;
628  }
629  (void) rpmDigestUpdate(dig->hdrctx, uh, uhc);
630  dig->nbytes += uhc;
631  (void) rpmswExit(op, dig->nbytes);
632  op->count--; /* XXX one too many */
633  uh = _free(uh);
634  } break;
635  case RPMSIGTAG_DSA:
636  /* Parse the parameters from the OpenPGP packets that will be needed. */
637  xx = pgpPktLen(she->p.ui8p, she->c, pp);
638  xx = rpmhkpLoadSignature(NULL, dig, pp);
639  if (dig->signature.version != 3 && dig->signature.version != 4) {
641  _("skipping package %s with unverifiable V%u signature\n"),
642  fn, dig->signature.version);
643  rc = RPMRC_FAIL;
644  goto exit;
645  }
646  /*@fallthrough@*/
647  case RPMSIGTAG_SHA1:
648  { void * uh = NULL;
649  rpmTagType uht;
650  rpmTagCount uhc;
651  unsigned char * hmagic = NULL;
652  size_t nmagic = 0;
653 
655  xx = headerGet(h, he, 0);
656  uht = he->t;
657  uh = he->p.ptr;
658  uhc = he->c;
659  if (!xx)
660  break;
661  (void) headerGetMagic(NULL, &hmagic, &nmagic);
662  op = (rpmop) pgpStatsAccumulator(dig, 10); /* RPMTS_OP_DIGEST */
663  (void) rpmswEnter(op, 0);
664  dig->hdrsha1ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
665  if (hmagic && nmagic > 0) {
666  (void) rpmDigestUpdate(dig->hdrsha1ctx, hmagic, nmagic);
667  dig->nbytes += nmagic;
668  }
669  (void) rpmDigestUpdate(dig->hdrsha1ctx, uh, uhc);
670  dig->nbytes += uhc;
671  (void) rpmswExit(op, dig->nbytes);
672  if ((rpmSigTag)she->tag == RPMSIGTAG_SHA1)
673  op->count--; /* XXX one too many */
674  uh = _free(uh);
675  } break;
676  case RPMSIGTAG_MD5:
677  /* Legacy signatures need the compressed payload in the digest too. */
678  op = (rpmop) pgpStatsAccumulator(dig, 10); /* RPMTS_OP_DIGEST */
679  (void) rpmswEnter(op, 0);
680  while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), fd)) > 0)
681  dig->nbytes += count;
682  (void) rpmswExit(op, dig->nbytes);
683  op->count--; /* XXX one too many */
684  dig->nbytes += nb; /* XXX include size of header blob. */
685  if (count < 0) {
686  rpmlog(RPMLOG_ERR, _("%s: Fread failed: %s\n"),
687  fn, Fstrerror(fd));
688  rc = RPMRC_FAIL;
689  goto exit;
690  }
691 
692  /* XXX Steal the digest-in-progress from the file handle. */
693  fdStealDigest(fd, dig);
694  break;
695  }
696 
699  buf[0] = '\0';
700  rc = rpmVerifySignature(dig, buf);
701  switch (rc) {
702  case RPMRC_OK: /* Signature is OK. */
703  rpmlog(RPMLOG_DEBUG, "%s: %s\n", fn, buf);
704  break;
705  case RPMRC_NOTTRUSTED: /* Signature is OK, but key is not trusted. */
706  case RPMRC_NOKEY: /* Public key is unavailable. */
707 #ifndef DYING
708  /* XXX Print NOKEY/NOTTRUSTED warning only once. */
709  { int lvl = (pgpStashKeyid(dig) ? RPMLOG_DEBUG : RPMLOG_WARNING);
710  rpmlog(lvl, "%s: %s\n", fn, buf);
711  } break;
712  case RPMRC_NOTFOUND: /* Signature is unknown type. */
713  rpmlog(RPMLOG_WARNING, "%s: %s\n", fn, buf);
714  break;
715 #else
716  case RPMRC_NOTFOUND: /* Signature is unknown type. */
717  case RPMRC_NOSIG: /* Signature is unavailable. */
718 #endif
719  default:
720  case RPMRC_FAIL: /* Signature does not verify. */
721  rpmlog(RPMLOG_ERR, "%s: %s\n", fn, buf);
722  break;
723  }
724 
725 exit:
726  if (rc != RPMRC_FAIL && h != NULL && hdrp != NULL) {
727 
728  /* Append (and remap) signature tags to the metadata. */
729  headerMergeLegacySigs(h, sigh);
730 
731  rpm3to4(h);
732 
733  /* Bump reference count for return. */
734  *hdrp = headerLink(h);
735  }
736  (void)headerFree(h);
737  h = NULL;
738 
739  /* Accumulate time reading package header. */
740  (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_READHDR),
741  fdstat_op(fd, FDSTAT_READ));
742  (void) rpmswSub(rpmtsOp(ts, RPMTS_OP_READHDR),
743  opsave);
744 
745 #ifdef NOTYET
746  /* Return RPMRC_NOSIG for MANDATORY signature verification. */
747  { rpmSigTag sigtag = pgpGetSigtag(dig);
748  switch (sigtag) {
749  default:
750  rc = RPMRC_NOSIG;
751  /*@fallthrough@*/
752  case RPMSIGTAG_RSA:
753  case RPMSIGTAG_DSA:
754  break;
755  }
756  }
757 #endif
758 
759  rpmtsCleanDig(ts);
760  (void)headerFree(sigh);
761  sigh = NULL;
762  return rc;
763 }
764 /*@=mods@*/
FDSTAT_t stats
rpmTagType t
Definition: rpmtag.h:505
const char * str
Definition: rpmtag.h:72
rpmTag tag
Definition: rpmtag.h:504
const char ** argv
Definition: rpmtag.h:74
rpmtime_t rpmswExit(rpmop op, ssize_t rc)
Exit timed operation.
Definition: rpmsw.c:264
int headerIsEntry(Header h, rpmTag tag)
Check if tag is in header.
Definition: header.c:1431
void headerMergeLegacySigs(Header h, const Header sigh)
Translate and merge legacy signature tags into header.
Definition: hdrNVR.c:242
int pgpPktLen(const rpmuint8_t *pkt, size_t pleft, pgpPkt pp)
Definition: rpmpgp.c:940
const void * pgpGetSig(pgpDig dig)
Get signature tag data, i.e.
Definition: rpmpgp.c:1247
enum rpmSigTag_e rpmSigTag
Definition: rpmtag.h:475
rpmuint32_t * ui32p
Definition: rpmtag.h:69
struct pgpDigParams_s * pgpDigParams
Definition: rpmiotypes.h:87
DIGEST_CTX rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags)
Initialize digest.
Definition: digest.c:244
int headerGet(Header h, HE_t he, unsigned int flags)
Retrieve extension or tag value from a header.
Definition: header.c:2222
int headerPut(Header h, HE_t he, unsigned int flags)
Add or append tag container to header.
Definition: header.c:2285
static unsigned int pgpGrab(const rpmuint8_t *s, size_t nbytes)
Return (native-endian) integer from big-endian representation.
Definition: rpmpgp.h:1077
enum pgpHashAlgo_e pgpHashAlgo
9.4.
The Header data structure.
rpmtime_t rpmswAdd(rpmop to, rpmop from)
Sum statistic counters.
Definition: rpmsw.c:280
static rpmVSFlags vsflags
Definition: rpmcache.c:547
int headerDel(Header h, HE_t he, unsigned int flags)
Remove tag container from header.
Definition: header.c:2304
rpmop rpmtsOp(rpmts ts, rpmtsOpX opx)
Retrieve operation timestamp from a transaction set.
Definition: pkgio.c:133
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:1257
enum rpmtsOpX_e rpmtsOpX
Indices for timestamps.
rpmiob rpmiobFree(rpmiob iob)
Destroy a I/O buffer instance.
static void rpmlog(int code, const char *fmt,...)
Definition: rpmlog.h:299
rpmiob rpmiobAppend(rpmiob iob, const char *s, size_t nl)
Append string to I/O buffer.
Definition: rpmiob.c:78
static void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int _flags)
Attach digest to fd.
static void rpm3to4(Header h)
Definition: package.c:409
pgpArmor pgpArmorUnwrap(rpmiob iob, rpmuint8_t **pkt, size_t *pktlen)
Parse armored OpenPGP packets from an iob.
Definition: rpmpgp.c:1397
static void providePackageNVR(Header h)
Definition: package.c:221
static void add_RPMTAG_SOURCERPM(Header h)
Definition: package.c:393
static rpmop fdstat_op(FD_t fd, fdOpX opx)
char * alloca()
unsigned int rpmuint32_t
Definition: rpmiotypes.h:25
struct _HE_s * HE_t
Definition: rpmtag.h:58
pgpVSFlags pgpDigVSFlags
Disabler bits(s) for signature/digest checking.
Definition: rpmpgp.c:1105
void rpmtsCleanDig(rpmts ts)
Free signature verification data.
Definition: pkgio.c:457
static void compressFilelist(Header h)
Convert absolute path tag to (dirname,basename,dirindex) tags.
Definition: package.c:99
const char * Fstrerror(FD_t fd)
strerror(3) clone.
Definition: rpmio.c:2401
void * ptr
Definition: rpmtag.h:66
int rpmDigestUpdate(DIGEST_CTX ctx, const void *data, size_t len)
Update context with next plain text buffer.
Definition: digest.c:907
unsigned int * keyids
Definition: package.c:34
int count
Definition: rpmsw.h:35
static void fdSetDig(FD_t fd, pgpDig dig)
unsigned char rpmuint8_t
Private int typedefs to avoid C99 portability issues.
Definition: rpmiotypes.h:23
enum evrFlags_e rpmsenseFlags
Definition: rpmevr.h:72
rpmTagData p
Definition: rpmtag.h:507
struct pgpPkt_s * pgpPkt
Definition: rpmiotypes.h:79
pgpDigParams pgpGetSignature(pgpDig dig)
Return OpenPGP signature parameters.
Definition: rpmpgp.c:1227
rpmRC rpmReadPackageFile(rpmts ts, FD_t fd, const char *fn, Header *hdrp)
Return package header from file handle, verifying digests/signatures.
Definition: package.c:428
rpmuint32_t pgpGetSigtag(pgpDig dig)
Get signature tag.
Definition: rpmpgp.c:1237
The FD_t File Handle data structure.
struct pgpDig_s * pgpDig
Definition: rpmiotypes.h:83
rpmTagCount c
Definition: rpmtag.h:508
Generate and verify rpm package signatures.
pgpVSFlags rpmVSFlags
Bit(s) to control digest and signature verification.
Definition: rpmts.h:30
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:941
int rpmswEnter(rpmop op, ssize_t rc)
Enter timed operation.
Definition: rpmsw.c:248
struct rpmop_s * rpmop
Definition: rpmsw.h:18
size_t Fread(void *buf, size_t size, size_t nmemb, FD_t fd)
fread(3) clone.
Definition: rpmio.c:2412
static unsigned int nextkeyid
Definition: package.c:42
rpmuint8_t * ui8p
Definition: rpmtag.h:67
enum rpmTagType_e rpmTagType
Definition: rpmtag.h:46
Cumulative statistics for an operation.
Definition: rpmsw.h:33
rpmiob rpmiobNew(size_t len)
Create an I/O buffer.
Definition: rpmiob.c:44
Header headerLink(Header h)
Reference a header instance.
enum rpmRC_e rpmRC
RPM return codes.
Definition: rpmtag.h:503
Methods to handle package elements.
rpmtime_t rpmswSub(rpmop to, rpmop from)
Subtract statistic counters.
Definition: rpmsw.c:292
char * stpcpy(char *dest, const char *src)
struct rpmts_s * rpmts
The RPM Transaction Set.
Definition: rpmtypes.h:14
#define _chk(_mask)
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:647
struct rpmiob_s * rpmiob
Definition: rpmiotypes.h:57
int headerNEVRA(Header h, const char **np, const char **ep, const char **vp, const char **rp, const char **ap)
Return name, epoch, version, release, arch strings from header.
Definition: hdrNVR.c:162
Structures and prototypes used for an "rpmts" transaction set.
static int dncmp(const void *a, const void *b)
Definition: package.c:85
static unsigned int nkeyids
Definition: package.c:40
#define _(Text)
Definition: system.h:30
static int pgpStashKeyid(pgpDig dig)
Remember current key id.
Definition: package.c:49
rpmRC rpmpkgRead(const char *fn, FD_t fd, void *ptr, const char **msg)
Read item from file descriptor.
Definition: pkgio.c:1647
enum rpmTag_e rpmTag
Definition: rpmtag.h:471
static void fdStealDigest(FD_t fd, pgpDig dig)
pgpDig rpmtsDig(rpmts ts)
Get OpenPGP packet parameters, i.e.
Definition: pkgio.c:442
void * pgpStatsAccumulator(pgpDig dig, int opx)
Return pgpDig container accumulator structure.
Definition: rpmpgp.c:1271
static unsigned int nkeyids_max
Definition: package.c:38
#define xrealloc
Definition: system.h:36
rpmuint32_t rpmTagCount
Definition: rpmtag.h:54
unsigned int append
Definition: rpmtag.h:512