rpm  5.4.14
rpmchecksig.c
Go to the documentation of this file.
1 
6 #include "system.h"
7 
8 #include <rpmio_internal.h>
9 #include <poptIO.h>
10 #include <rpmbc.h> /* XXX beecrypt base64 */
11 
12 #define _RPMHKP_INTERNAL /* XXX internal prototypes. */
13 #include <rpmhkp.h>
14 
15 #include <rpmtag.h>
16 #include <rpmtypes.h>
17 #define _RPMEVR_INTERNAL /* XXX RPMSENSE_KEYRING */
18 #include <rpmevr.h>
19 #define _RPMDB_INTERNAL /* XXX db_txn */
20 #include <rpmdb.h>
21 #include <rpmtxn.h>
22 #include <rpmxar.h>
23 #include <pkgio.h>
24 #include "signature.h"
25 
26 #define _RPMTS_INTERNAL /* XXX ts->hkp */
27 #include <rpmts.h>
28 
29 #include "rpmgi.h"
30 
31 #include <rpmversion.h>
32 #include <rpmcli.h>
33 
34 #include "debug.h"
35 
36 /*@access FD_t @*/ /* XXX stealing digests */
37 /*@access Header @*/ /* XXX void * arg */
38 /*@access pgpDig @*/
39 /*@access pgpDigParams @*/
40 
41 #ifdef __cplusplus
42 GENfree(struct rpmlead *)
43 GENfree(rpmuint8_t **)
44 #endif /* __cplusplus */
45 
46 /*@unchecked@*/
47 int _print_pkts = 0;
48 
51 static int manageFile(/*@out@*/ FD_t *fdp,
52  /*@null@*/ /*@out@*/ const char **fnp,
53  int flags, /*@unused@*/ int rc)
54  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
55  /*@modifies *fdp, *fnp, rpmGlobalMacroContext,
56  fileSystem, internalState @*/
57 {
58  const char *fn;
59  FD_t fd;
60 
61  if (fdp == NULL) /* programmer error */
62  return 1;
63 
64  /* close and reset *fdp to NULL */
65  if (*fdp && (fnp == NULL || *fnp == NULL)) {
66  (void) Fclose(*fdp);
67  *fdp = NULL;
68  return 0;
69  }
70 
71  /* open a file and set *fdp */
72  if (*fdp == NULL && fnp != NULL && *fnp != NULL) {
73  fd = Fopen(*fnp, ((flags & O_WRONLY) ? "w.fdio" : "r.fdio"));
74  if (fd == NULL || Ferror(fd)) {
75  rpmlog(RPMLOG_ERR, _("%s: open failed: %s\n"), *fnp,
76  Fstrerror(fd));
77  return 1;
78  }
79  *fdp = fd;
80  return 0;
81  }
82 
83  /* open a temp file */
84  if (*fdp == NULL && (fnp == NULL || *fnp == NULL)) {
85  fn = NULL;
86  if (rpmTempFile(NULL, (fnp ? &fn : NULL), &fd)) {
87  rpmlog(RPMLOG_ERR, _("rpmTempFile failed\n"));
88  return 1;
89  }
90  if (fnp != NULL)
91  *fnp = fn;
92 /*@-refcounttrans@*/ /* FIX: XfdLink/XfdFree annotation */
93  *fdp = fdLink(fd, "manageFile return");
94  fd = fdFree(fd, "manageFile return");
95 /*@=refcounttrans@*/
96  return 0;
97  }
98 
99  /* no operation */
100  if (*fdp != NULL && fnp != NULL && *fnp != NULL)
101  return 0;
102 
103  /* XXX never reached */
104  return 1;
105 }
106 
110 static int copyFile(FD_t *sfdp, const char **sfnp,
111  FD_t *tfdp, const char **tfnp)
112  /*@globals rpmGlobalMacroContext, h_errno,
113  fileSystem, internalState @*/
114  /*@modifies *sfdp, *sfnp, *tfdp, *tfnp, rpmGlobalMacroContext,
115  fileSystem, internalState @*/
116 {
117  unsigned char buf[BUFSIZ];
118  ssize_t count;
119  int rc = 1;
120 
121  if (manageFile(sfdp, sfnp, O_RDONLY, 0))
122  goto exit;
123  if (manageFile(tfdp, tfnp, O_WRONLY|O_CREAT|O_TRUNC, 0))
124  goto exit;
125 
126  while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), *sfdp)) > 0)
127  {
128  if (Fwrite(buf, sizeof(buf[0]), count, *tfdp) != (size_t)count) {
129  rpmlog(RPMLOG_ERR, _("%s: Fwrite failed: %s\n"), *tfnp,
130  Fstrerror(*tfdp));
131  goto exit;
132  }
133  }
134  if (count < 0) {
135  rpmlog(RPMLOG_ERR, _("%s: Fread failed: %s\n"), *sfnp, Fstrerror(*sfdp));
136  goto exit;
137  }
138  if (Fflush(*tfdp) != 0) {
139  rpmlog(RPMLOG_ERR, _("%s: Fflush failed: %s\n"), *tfnp,
140  Fstrerror(*tfdp));
141  goto exit;
142  }
143 
144  rc = 0;
145 
146 exit:
147  if (*sfdp) (void) manageFile(sfdp, NULL, 0, rc);
148  if (*tfdp) (void) manageFile(tfdp, NULL, 0, rc);
149  return rc;
150 }
151 
159 static int getSignid(Header sigh, rpmSigTag sigtag, unsigned char * signid)
160  /*@globals fileSystem, internalState @*/
161  /*@modifies *signid, fileSystem, internalState @*/
162 {
163  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
164  int rc = 1;
165  int xx;
166 
167  he->tag = (rpmTag) sigtag;
168  xx = headerGet(sigh, he, 0);
169  if (xx && he->p.ptr != NULL) {
171 
172  /* XXX expose ppSignid() from rpmhkp.c? */
173  pgpPkt pp = (pgpPkt) alloca(sizeof(*pp));
174  (void) pgpPktLen(he->p.ui8p, he->c, pp);
175  if (!rpmhkpLoadSignature(NULL, dig, pp)) {
176  memcpy(signid, dig->signature.signid, sizeof(dig->signature.signid));
177  rc = 0;
178  }
179 
180  he->p.ptr = _free(he->p.ptr);
181  dig = pgpDigFree(dig);
182  }
183  return rc;
184 }
185 
193 static int rpmReSign(/*@unused@*/ rpmts ts,
194  QVA_t qva, const char ** argv)
195  /*@globals rpmGlobalMacroContext, h_errno,
196  fileSystem, internalState @*/
197  /*@modifies ts, rpmGlobalMacroContext,
198  fileSystem, internalState @*/
199 {
200  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
201  rpmgi gi = NULL;
202  FD_t fd = NULL;
203  FD_t ofd = NULL;
204  struct rpmlead *lead = NULL;
205  rpmSigTag sigtag;
206  const char *sigtarget = NULL;
207  char tmprpm[1024+1];
208  Header sigh = NULL;
209  int res = 1; /* XXX assume failure */
210  int deleting = (qva->qva_mode == RPMSIGN_DEL_SIGNATURE);
211  rpmRC rpmrc = RPMRC_OK;
212  int xx;
213  int i;
214  mode_t mode;
215 
216  tmprpm[0] = '\0';
217 
218  if (argv)
219  { /* start-of-arg-iteration */
222  rpmgiFlags _giFlags = RPMGI_NONE;
223 
224  gi = rpmgiNew(ts, tag, NULL, 0);
225 /*@-mods@*/
226  if (rpmioFtsOpts == 0)
228 /*@=mods@*/
229  rpmrc = rpmgiSetArgs(gi, argv, rpmioFtsOpts, (rpmgiFlags)(_giFlags|RPMGI_NOHEADER));
230 
231  while ((rpmrc = rpmgiNext(gi)) == RPMRC_OK) {
232  const char * fn = rpmgiHdrPath(gi);
233  const char * tfn;
234 
235  fprintf(stdout, "%s:\n", fn);
236 
237 /*@-modobserver@*/ /* XXX rpmgiHdrPath should not be observer */
238  if (manageFile(&fd, &fn, O_RDONLY, 0))
239  goto exit;
240 /*@=modobserver@*/
241 
242  { const char item[] = "Lead";
243  const char * msg = NULL;
244  rpmRC rc = rpmpkgRead(item, fd, &lead, &msg);
245  if (rc != RPMRC_OK) {
246  rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item, msg);
247  msg = _free(msg);
248  goto exit;
249  }
250  msg = _free(msg);
251  }
252 
253  { const char item[] = "Signature";
254  const char * msg = NULL;
255  rpmRC rc = rpmpkgRead(item, fd, &sigh, &msg);
256  switch (rc) {
257  default:
258  rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item,
259  (msg && *msg ? msg : ""));
260  msg = _free(msg);
261  goto exit;
262  /*@notreached@*/ /*@switchbreak@*/ break;
263  case RPMRC_OK:
264  if (sigh == NULL) {
265  rpmlog(RPMLOG_ERR, _("%s: No signature available\n"), fn);
266  goto exit;
267  }
268  /*@switchbreak@*/ break;
269  }
270  msg = _free(msg);
271  }
272 
273  /* Write the header and archive to a temp file */
274  /* ASSERT: ofd == NULL && sigtarget == NULL */
275 /*@-modobserver@*/ /* XXX rpmgiHdrPath should not be observer */
276  if (copyFile(&fd, &fn, &ofd, &sigtarget))
277  goto exit;
278 /*@=modobserver@*/
279  /* Both fd and ofd are now closed. sigtarget contains tempfile name. */
280  /* ASSERT: fd == NULL && ofd == NULL */
281 
282  /* Lose the immutable region (if present). */
284  xx = headerGet(sigh, he, 0);
285  if (xx) {
286  HE_t ohe = (HE_t) memset(alloca(sizeof(*ohe)), 0, sizeof(*ohe));
287  HeaderIterator hi;
288  Header oh;
289  Header nh;
290 
291  nh = headerNew();
292  if (nh == NULL) {
293  he->p.ptr = _free(he->p.ptr);
294  goto exit;
295  }
296 
297  oh = headerCopyLoad(he->p.ptr);
298  for (hi = headerInit(oh);
299  headerNext(hi, ohe, 0);
300  ohe->p.ptr = _free(ohe->p.ptr))
301  {
302  if (ohe->p.ptr) {
303  xx = headerPut(nh, ohe, 0);
304  }
305  }
306  hi = headerFini(hi);
307  (void)headerFree(oh);
308  oh = NULL;
309 
310  (void)headerFree(sigh);
311  sigh = NULL;
312  sigh = headerLink(nh);
313  (void)headerFree(nh);
314  nh = NULL;
315  }
316 
317 if (sigh != NULL) {
318  /* Eliminate broken digest values. */
320  xx = headerDel(sigh, he, 0);
322  xx = headerDel(sigh, he, 0);
324  xx = headerDel(sigh, he, 0);
326  xx = headerDel(sigh, he, 0);
327 
328  /* Toss and recalculate header+payload size and digests. */
329  { static const rpmuint32_t sigs[] =
331  size_t nsigs = sizeof(sigs) / sizeof(sigs[0]);
332  for (i = 0; i < (int)nsigs; i++) {
333  he->tag = (rpmTag)sigs[i];
334  xx = headerDel(sigh, he, 0);
335  xx = rpmAddSignature(sigh, sigtarget, (rpmSigTag) he->tag, qva->passPhrase);
336  if (xx)
337  goto exit;
338  }
339  }
340 
341  if (deleting) {
342  /* Nuke all the signature tags. */
343  static const rpmuint32_t sigs[] =
346  size_t nsigs = sizeof(sigs) / sizeof(sigs[0]);
347  for (i = 0; i < (int)nsigs; i++) {
348  he->tag = (rpmTag)sigs[i];
349  xx = headerDel(sigh, he, 0);
350  }
351  } else { /* If gpg/pgp is configured, replace the signature. */
352  int addsig = 0;
353  sigtag = RPMSIGTAG_GPG;
354  addsig = 1;
355 
356  if (addsig) {
357  unsigned char oldsignid[8], newsignid[8];
358 
359  /* Grab the old signature fingerprint (if any) */
360  memset(oldsignid, 0, sizeof(oldsignid));
361  xx = getSignid(sigh, sigtag, oldsignid);
362 
363  switch (sigtag) {
364  default:
365  /*@switchbreak@*/ break;
366  case RPMSIGTAG_DSA:
367  he->tag = (rpmTag)RPMSIGTAG_GPG;
368  xx = headerDel(sigh, he, 0);
369  /*@switchbreak@*/ break;
370  case RPMSIGTAG_RSA:
371  he->tag = (rpmTag)RPMSIGTAG_PGP;
372  xx = headerDel(sigh, he, 0);
373  /*@switchbreak@*/ break;
374  case RPMSIGTAG_GPG:
375  he->tag = (rpmTag)RPMSIGTAG_PGP;
376  xx = headerDel(sigh, he, 0);
377  he->tag = (rpmTag)RPMSIGTAG_DSA;
378  xx = headerDel(sigh, he, 0);
379  /*@fallthrough@*/
380  case RPMSIGTAG_PGP5:
381  case RPMSIGTAG_PGP:
382  he->tag = (rpmTag)RPMSIGTAG_RSA;
383  xx = headerDel(sigh, he, 0);
384  /*@switchbreak@*/ break;
385  }
386 
387  he->tag = (rpmTag)sigtag;
388  xx = headerDel(sigh, he, 0);
389  xx = rpmAddSignature(sigh, sigtarget, sigtag, qva->passPhrase);
390  if (xx)
391  goto exit;
392 
393  /* If package was previously signed, check for same signer. */
394  memset(newsignid, 0, sizeof(newsignid));
395  if (memcmp(oldsignid, newsignid, sizeof(oldsignid))) {
396 
397  /* Grab the new signature fingerprint */
398  xx = getSignid(sigh, sigtag, newsignid);
399 
400  /* If same signer, skip resigning the package. */
401  if (!memcmp(oldsignid, newsignid, sizeof(oldsignid))) {
402 
404  _("%s: was already signed by key ID %s, skipping\n"),
405  fn, pgpHexStr(newsignid+4, sizeof(newsignid)-4));
406 
407  /* Clean up intermediate target */
408  xx = Unlink(sigtarget);
409  sigtarget = _free(sigtarget);
410  continue;
411  }
412  }
413  }
414  }
415 
416  /* Reallocate the signature into one contiguous region. */
418  if (sigh == NULL) /* XXX can't happen */
419  goto exit;
420 }
421 
422  /* Write the lead/signature of the output rpm */
423  (void) stpcpy( stpcpy(tmprpm, fn), ".XXXXXX");
424 
425 #if defined(HAVE_MKSTEMP)
426  mode = umask(0077);
427  (void) close(mkstemp(tmprpm));
428  (void) umask(mode);
429 #else
430  (void) mktemp(tmprpm);
431 #endif
432  tfn = tmprpm;
433 
434  if (manageFile(&ofd, &tfn, O_WRONLY|O_CREAT|O_TRUNC, 0))
435  goto exit;
436 
437  { const char item[] = "Lead";
438  const char * msg = NULL;
439  rpmRC rc = rpmpkgWrite(item, ofd, lead, &msg);
440  if (rc != RPMRC_OK) {
441  rpmlog(RPMLOG_ERR, "%s: %s: %s\n", tfn, item, Fstrerror(ofd));
442  msg = _free(msg);
443  goto exit;
444  }
445  msg = _free(msg);
446  }
447 
448  { const char item[] = "Signature";
449  const char * msg = NULL;
450  rpmRC rc = rpmpkgWrite(item, ofd, sigh, &msg);
451  if (rc != RPMRC_OK) {
452  rpmlog(RPMLOG_ERR, "%s: %s: %s\n", tfn, item, Fstrerror(ofd));
453  msg = _free(msg);
454  goto exit;
455  }
456  msg = _free(msg);
457  }
458  (void)headerFree(sigh);
459  sigh = NULL;
460 
461  /* Append the header and archive from the temp file */
462  /* ASSERT: fd == NULL && ofd != NULL */
463  if (copyFile(&fd, &sigtarget, &ofd, &tfn))
464  goto exit;
465  /* Both fd and ofd are now closed. */
466  /* ASSERT: fd == NULL && ofd == NULL */
467 
468  /* Move final target into place. */
469  xx = Unlink(fn);
470  xx = Rename(tfn, fn);
471  tmprpm[0] = '\0';
472 
473  /* Clean up intermediate target */
474  xx = Unlink(sigtarget);
475  sigtarget = _free(sigtarget);
476  }
477 
478  /* XXX disambiguate end-of-iteration from item failures. */
479  if (rpmrc == RPMRC_NOTFOUND)
480  rpmrc = (rpmRC) rpmgiRc(gi);
481 
482  gi = rpmgiFree(gi);
483 
484  } /* end-of-arg-iteration */
485 
486  if (rpmrc == RPMRC_OK)
487  res = 0;
488 
489 exit:
490  if (fd) (void) manageFile(&fd, NULL, 0, res);
491  if (ofd) (void) manageFile(&ofd, NULL, 0, res);
492 
493  lead = _free(lead);
494  (void)headerFree(sigh);
495  sigh = NULL;
496 
497  if (sigtarget) {
498  xx = Unlink(sigtarget);
499  sigtarget = _free(sigtarget);
500  }
501  if (tmprpm[0] != '\0') {
502  xx = Unlink(tmprpm);
503  tmprpm[0] = '\0';
504  }
505 
506  return res;
507 }
508 
509 rpmRC rpmcliImportPubkey(const rpmts ts, const unsigned char * pkt, ssize_t pktlen)
510 {
511  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
512  static unsigned char zeros[] =
513  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
514  const char * afmt = "%{pubkeys:armor}";
515  const char * group = "Public Keys";
516  const char * license = "pubkey";
517  const char * buildhost = "localhost";
518  rpmuint32_t pflags = (RPMSENSE_KEYRING|RPMSENSE_EQUAL);
519  rpmuint32_t zero = 0;
520  pgpDig dig = NULL;
521  pgpDigParams pubp = NULL;
522  const char * d = NULL;
523  const char * enc = NULL;
524  const char * n = NULL;
525  const char * u = NULL;
526  const char * v = NULL;
527  const char * r = NULL;
528  const char * evr = NULL;
529  Header h = NULL;
530  rpmRC rc = RPMRC_FAIL; /* assume failure */
531  char * t;
532  int xx;
533 rpmhkp hkp = NULL;
534 pgpPkt pp = (pgpPkt) alloca(sizeof(*pp));
535 int validate = 1;
536 
537  /* XXX coverity #1035781 */
538  /* Validate the pubkey. */
539  if (ts->hkp == NULL)
540  ts->hkp = rpmhkpNew(NULL, 0);
541  hkp = rpmhkpLink(ts->hkp);
542 hkp->pkt = (rpmuint8_t *)pkt;
543 hkp->pktlen = pktlen;
544 
545  if (pkt == NULL || pktlen <= 0)
546  goto exit;
547  if (rpmtsOpenDB(ts, (O_RDWR|O_CREAT)))
548  goto exit;
549 
550 /*@-moduncon@*/
551  if ((enc = b64encode(pkt, pktlen)) == NULL)
552  goto exit;
553 /*@=moduncon@*/
554 
556  pubp = pgpGetPubkey(dig);
557 
558  xx = pgpGrabPkts(hkp->pkt, hkp->pktlen, &hkp->pkts, &hkp->npkts);
559  if (!xx)
560  (void) pgpPubkeyFingerprint(hkp->pkt, hkp->pktlen, hkp->keyid);
561  memcpy(pubp->signid, hkp->keyid, sizeof(pubp->signid)); /* XXX useless */
562 
563  xx = pgpPktLen(hkp->pkt, hkp->pktlen, pp);
564 
565  xx = rpmhkpLoadKey(hkp, dig, 0, 0);
566 
567  /* Validate pubkey self-signatures. */
568  if (validate) {
569  rpmRC yy = rpmhkpValidate(hkp, NULL);
570  switch (yy) {
571  case RPMRC_OK:
572  break;
573  case RPMRC_NOTFOUND:
574  case RPMRC_FAIL: /* XXX remap to NOTFOUND? */
575  case RPMRC_NOTTRUSTED:
576  case RPMRC_NOKEY:
577  default:
578 #ifdef NOTYET /* XXX make check-pubkey fails?!? . */
579  rc = yy;
580  goto exit;
581 #endif
582  /*@notreached@*/ break;
583  }
584  }
585 
586  /* XXX hack up a user id (if not already present) */
587  if (pubp->userid == NULL) {
588  if (hkp->uidx >= 0 && hkp->uidx < hkp->npkts) {
589  size_t nb = pgpPktLen(hkp->pkts[hkp->uidx], hkp->pktlen, pp);
590  char * t;
591  nb = pp->hlen;
592  t = (char *) memcpy(xmalloc(nb + 1), pp->u.u->userid, nb);
593  t[nb] = '\0';
594  pubp->userid = t;
595  } else
596  pubp->userid = xstrdup(pgpHexStr(pubp->signid+4, 4));
597  }
598 
599 #ifdef DYING
600 _rpmhkpDumpDig(__FUNCTION__, dig);
601 #endif
602 
603  /* Build header elements. */
604  if (!memcmp(pubp->signid, zeros, sizeof(pubp->signid))
605  || !memcmp(pubp->time, zeros, sizeof(pubp->time))
606  || pubp->userid == NULL)
607  goto exit;
608 
609  v = t = (char *) xmalloc(16+1);
610  t = stpcpy(t, pgpHexStr(pubp->signid, sizeof(pubp->signid)));
611 
612  r = t = (char *) xmalloc(8+1);
613  t = stpcpy(t, pgpHexStr(pubp->time, sizeof(pubp->time)));
614 
615  n = t = (char *) xmalloc(sizeof("gpg()")+8);
616  t = stpcpy( stpcpy( stpcpy(t, "gpg("), v+8), ")");
617 
618  { const char * userid =
619  (pubp->userid ? pubp->userid : pgpHexStr(pubp->signid+4, 4));
620  u = t = (char *) xmalloc(sizeof("gpg()")+strlen(userid));
621  t = stpcpy( stpcpy( stpcpy(t, "gpg("), userid), ")");
622  }
623 
624  evr = t = (char *) xmalloc(sizeof("4X:-")+strlen(v)+strlen(r));
625  t = stpcpy(t, (pubp->version == 4 ? "4:" : "3:"));
626  t = stpcpy( stpcpy( stpcpy(t, v), "-"), r);
627 
628  /* Check for pre-existing header. */
629 
630  /* Build pubkey header. */
631  h = headerNew();
632 
633  he->append = 1;
634 
635  he->tag = RPMTAG_PUBKEYS;
636  he->t = RPM_STRING_ARRAY_TYPE;
637  he->p.argv = &enc;
638  he->c = 1;
639  xx = headerPut(h, he, 0);
640 
641  he->append = 0;
642 
643  d = headerSprintf(h, afmt, NULL, rpmHeaderFormats, NULL);
644  if (d == NULL)
645  goto exit;
646 
647  he->t = RPM_STRING_TYPE;
648  he->c = 1;
649  he->tag = RPMTAG_NAME;
650  he->p.str = xstrdup("gpg-pubkey");
651  xx = headerPut(h, he, 0);
652  he->p.ptr = _free(he->p.ptr);
653  he->tag = RPMTAG_VERSION;
654  he->p.str = v+8;
655  xx = headerPut(h, he, 0);
656  he->tag = RPMTAG_RELEASE;
657  he->p.str = xstrdup(r);
658  xx = headerPut(h, he, 0);
659  he->p.ptr = _free(he->p.ptr);
660 
661  /* Add Summary/Description/Group. */
662  he->tag = RPMTAG_DESCRIPTION;
663  he->p.str = xstrdup(d);
664 #if defined(SUPPORT_I18NSTRING_TYPE)
665  xx = headerAddI18NString(h, he->tag, he->p.str, "C");
666 #else
667  xx = headerPut(h, he, 0);
668 #endif
669  he->p.ptr = _free(he->p.ptr);
670 
671  he->tag = RPMTAG_GROUP;
672  he->p.str = xstrdup(group);
673 #if defined(SUPPORT_I18NSTRING_TYPE)
674  xx = headerAddI18NString(h, he->tag, he->p.str, "C");
675 #else
676  xx = headerPut(h, he, 0);
677 #endif
678  he->p.ptr = _free(he->p.ptr);
679 
680  he->tag = RPMTAG_SUMMARY;
681  he->p.str = xstrdup(u);
682 #if defined(SUPPORT_I18NSTRING_TYPE)
683  xx = headerAddI18NString(h, he->tag, he->p.str, "C");
684 #else
685  xx = headerPut(h, he, 0);
686 #endif
687  he->p.ptr = _free(he->p.ptr);
688 
689 #ifdef NOTYET /* XXX can't erase pubkeys with "pubkey" arch. */
690  /* Add a "pubkey" arch/os to avoid missing value NULL ptrs. */
691  he->tag = RPMTAG_ARCH;
692  he->p.str = "pubkey";
693  xx = headerPut(h, he, 0);
694  he->tag = RPMTAG_OS;
695  he->p.str = "pubkey";
696  xx = headerPut(h, he, 0);
697 #endif
698 
699  he->tag = RPMTAG_LICENSE;
700  he->p.str = xstrdup(license);
701  xx = headerPut(h, he, 0);
702  he->p.ptr = _free(he->p.ptr);
703 
704  he->tag = RPMTAG_SIZE;
705  he->t = RPM_UINT32_TYPE;
706  he->p.ui32p = &zero;
707  he->c = 1;
708  xx = headerPut(h, he, 0);
709 
710  he->append = 1;
711 
712  /* Provides: gpg(IDENTITY) = PUBKEYVERSIONTYPE:PUBKEYID-CREATION */
713  he->tag = RPMTAG_PROVIDENAME;
714  he->t = RPM_STRING_ARRAY_TYPE;
715  he->p.argv = &u;
716  he->c = 1;
717  xx = headerPut(h, he, 0);
719  he->t = RPM_STRING_ARRAY_TYPE;
720  he->p.argv = &evr;
721  he->c = 1;
722  xx = headerPut(h, he, 0);
723  he->tag = RPMTAG_PROVIDEFLAGS;
724  he->t = RPM_UINT32_TYPE;
725  he->p.ui32p = &pflags;
726  he->c = 1;
727  xx = headerPut(h, he, 0);
728 
729  /* Provides: gpg(PUBKEYID) = PUBKEYVERSION:PUBKEYID-CREATION */
730  he->tag = RPMTAG_PROVIDENAME;
731  he->t = RPM_STRING_ARRAY_TYPE;
732  he->p.argv = &n;
733  he->c = 1;
734  xx = headerPut(h, he, 0);
736  he->t = RPM_STRING_ARRAY_TYPE;
737  he->p.argv = &evr;
738  he->c = 1;
739  xx = headerPut(h, he, 0);
740  he->tag = RPMTAG_PROVIDEFLAGS;
741  he->t = RPM_UINT32_TYPE;
742  he->p.ui32p = &pflags;
743  he->c = 1;
744  xx = headerPut(h, he, 0);
745 
746  he->append = 0;
747 
748  he->tag = RPMTAG_RPMVERSION;
749  he->t = RPM_STRING_TYPE;
750  he->p.str = xstrdup(RPMVERSION);
751  he->c = 1;
752  xx = headerPut(h, he, 0);
753  he->p.ptr = _free(he->p.ptr);
754 
755  /* XXX W2DO: tag value inherited from parent? */
756  he->tag = RPMTAG_BUILDHOST;
757  he->t = RPM_STRING_TYPE;
758  he->p.str = xstrdup(buildhost);
759  he->c = 1;
760  xx = headerPut(h, he, 0);
761  he->p.ptr = _free(he->p.ptr);
762 
763  { rpmuint32_t tid = rpmtsGetTid(ts);
764  he->tag = RPMTAG_INSTALLTIME;
765  he->t = RPM_UINT32_TYPE;
766  he->p.ui32p = &tid;
767  he->c = 1;
768  xx = headerPut(h, he, 0);
769  /* XXX W2DO: tag value inherited from parent? */
770  he->tag = RPMTAG_BUILDTIME;
771  he->t = RPM_UINT32_TYPE;
772  he->p.ui32p = &tid;
773  he->c = 1;
774  xx = headerPut(h, he, 0);
775  }
776 
777 #ifdef NOTYET
778  /* XXX W2DO: tag value inherited from parent? */
779  he->tag = RPMTAG_SOURCERPM;
780  he->t = RPM_STRING_TYPE;
781  he->p.str = fn;
782  he->c = 1;
783  xx = headerPut(h, he, 0);
784 #endif
785 
786  /* Reallocate the pubkey header into an immutable region. */
788  h = headerReload(h, he->tag);
789  { size_t length = 0;
790  he->t = RPM_BIN_TYPE;
791  he->p.ptr = headerUnload(h, &length);
792  he->c = length;
793  }
794 
795  /* Calculate the header-only SHA1 digest. */
797  unsigned char * hmagic = NULL;
798  size_t nmagic = 0;
799  const char * SHA1 = NULL;
800 
801  (void) headerGetMagic(NULL, &hmagic, &nmagic);
802  if (hmagic && nmagic > 0)
803  (void) rpmDigestUpdate(ctx, hmagic, nmagic);
804  (void) rpmDigestUpdate(ctx, he->p.ptr, he->c);
805  (void) rpmDigestFinal(ctx, &SHA1, NULL, 1);
806  he->p.ptr = _free(he->p.ptr);
807 
808  if (SHA1 == NULL)
809  goto exit;
810  he->tag = RPMTAG_SHA1HEADER;
811  he->t = RPM_STRING_TYPE;
812  he->p.str = SHA1;
813  he->c = 1;
814  xx = headerPut(h, he, 0);
815  SHA1 = _free(SHA1);
816  }
817 
818  he->tag = RPMTAG_PACKAGECOLOR;
819  he->t = RPM_UINT32_TYPE;
820  he->p.ui32p = &zero;
821  he->c = 1;
822  xx = headerPut(h, he, 0);
823 
824  /* Add header to database. */
825  xx = rpmtxnBegin(rpmtsGetRdb(ts), NULL, NULL);
826  xx = rpmdbAdd(rpmtsGetRdb(ts), rpmtsGetTid(ts), h, NULL);
827  if (xx != 0) {
828  xx = rpmtxnAbort(rpmtsGetRdb(ts)->db_txn);
829  rpmtsGetRdb(ts)->db_txn = NULL;
830  goto exit;
831  } else
832  xx = rpmtxnCommit(rpmtsGetRdb(ts)->db_txn);
833  rpmtsGetRdb(ts)->db_txn = NULL;
834  xx = rpmtxnCheckpoint(rpmtsGetRdb(ts));
835  rc = RPMRC_OK;
836 
837 exit:
838  /* Clean up. */
839 hkp->pkt = NULL;
840 hkp->pktlen = 0;
841 hkp->pkts = _free(hkp->pkts);
842 hkp->npkts = 0;
843  (void) rpmhkpFree(hkp);
844  hkp = NULL;
845  (void)headerFree(h);
846  h = NULL;
847  dig = pgpDigFree(dig);
848  n = _free(n);
849  u = _free(u);
850  v = _free(v);
851  r = _free(r);
852  evr = _free(evr);
853  enc = _free(enc);
854  d = _free(d);
855 
856  return rc;
857 }
858 
867 static int rpmcliImportPubkeys(const rpmts ts,
868  /*@unused@*/ QVA_t qva,
869  /*@null@*/ const char ** argv)
870  /*@globals rpmGlobalMacroContext, h_errno,
871  fileSystem, internalState @*/
872  /*@modifies ts, rpmGlobalMacroContext,
873  fileSystem, internalState @*/
874 {
875  const char * fn;
876  rpmuint8_t * pkt = NULL;
877  size_t pktlen = 0;
878  char * t = NULL;
879  int res = 0;
880  rpmRC rpmrc;
881  int rc;
882 
883  if (argv == NULL) return res;
884 
885  while ((fn = *argv++) != NULL) {
886 
887  rpmtsClean(ts);
888  pkt = _free(pkt);
889  t = _free(t);
890 
891  /* If arg looks like a keyid, then attempt keyserver retrieve. */
892  if (fn[0] == '0' && fn[1] == 'x') {
893  const char * s;
894  int i;
895  for (i = 0, s = fn+2; *s && isxdigit(*s); s++, i++)
896  {};
897  if (i == 8 || i == 16) {
898  t = rpmExpand("%{_hkp_keyserver_query}", fn, NULL);
899  if (t && *t != '%')
900  fn = t;
901  }
902  }
903 
904  /* Read pgp packet. */
905  if ((rc = pgpReadPkts(fn, &pkt, &pktlen)) <= 0) {
906  rpmlog(RPMLOG_ERR, _("%s: import read failed(%d).\n"), fn, rc);
907  res++;
908  continue;
909  }
910  if (rc != PGPARMOR_PUBKEY) {
911  rpmlog(RPMLOG_ERR, _("%s: not an armored public key.\n"), fn);
912  res++;
913  continue;
914  }
915 
916  /* Import pubkey packet(s). */
917  if ((rpmrc = rpmcliImportPubkey(ts, pkt, pktlen)) != RPMRC_OK) {
918  rpmlog(RPMLOG_ERR, _("%s: import failed.\n"), fn);
919  res++;
920  continue;
921  }
922 
923  }
924 
925 rpmtsClean(ts);
926  pkt = _free(pkt);
927  t = _free(t);
928  return res;
929 }
930 
934 static rpmRC readFile(FD_t fd, const char * fn)
935  /*@globals fileSystem, internalState @*/
936  /*@modifies fd, fileSystem, internalState @*/
937 {
938 rpmxar xar = fdGetXAR(fd);
939 pgpDig dig = fdGetDig(fd);
940  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
941  unsigned char buf[4*BUFSIZ];
942  ssize_t count;
943  unsigned ix;
944  rpmRC rc;
945  int xx;
946 
947  dig->nbytes = 0;
948 
949  /* Read the header from the package. */
950  { Header h = NULL;
951  const char item[] = "Header";
952  const char * msg = NULL;
953  rc = rpmpkgRead(item, fd, &h, &msg);
954  if (rc != RPMRC_OK) {
955  rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item, msg);
956  msg = _free(msg);
957  goto exit;
958  }
959  msg = _free(msg);
960 
961  dig->nbytes += headerSizeof(h);
962 
963  /* Fish out the autosign pubkey (if present). */
964  he->tag = RPMTAG_PUBKEYS;
965  xx = headerGet(h, he, 0);
966  if (xx && he->p.argv != NULL && he->c > 0)
967  switch (he->t) {
968  default:
969  break;
971  ix = he->c - 1; /* XXX FIXME: assumes last pubkey */
972  dig->pub = _free(dig->pub);
973  dig->publen = 0;
974  { rpmiob iob = rpmiobNew(0);
975  iob = rpmiobAppend(iob, he->p.argv[ix], 0);
976  xx = pgpArmorUnwrap(iob, (rpmuint8_t **)&dig->pub, &dig->publen);
977  iob = rpmiobFree(iob);
978  }
979  if (xx != PGPARMOR_PUBKEY) {
980  dig->pub = _free(dig->pub);
981  dig->publen = 0;
982  }
983  break;
984  }
985  he->p.ptr = _free(he->p.ptr);
986 
988  unsigned char * hmagic = NULL;
989  size_t nmagic = 0;
990 
992  xx = headerGet(h, he, 0);
993  if (!xx || he->p.ptr == NULL) {
994  (void)headerFree(h);
995  h = NULL;
996  rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, _("headerGet failed"),
997  _("failed to retrieve original header\n"));
998  rc = RPMRC_FAIL;
999  goto exit;
1000  }
1001  (void) headerGetMagic(NULL, &hmagic, &nmagic);
1002  dig->hdrsha1ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
1003  if (hmagic && nmagic > 0)
1004  (void) rpmDigestUpdate(dig->hdrsha1ctx, hmagic, nmagic);
1005  (void) rpmDigestUpdate(dig->hdrsha1ctx, he->p.ptr, he->c);
1006  dig->hdrctx = rpmDigestInit((pgpHashAlgo)dig->signature.hash_algo, RPMDIGEST_NONE);
1007  if (hmagic && nmagic > 0)
1008  (void) rpmDigestUpdate(dig->hdrctx, hmagic, nmagic);
1009  (void) rpmDigestUpdate(dig->hdrctx, he->p.ptr, he->c);
1010  he->p.ptr = _free(he->p.ptr);
1011  }
1012  (void)headerFree(h);
1013  h = NULL;
1014  }
1015 
1016  if (xar != NULL) {
1017  const char item[] = "Payload";
1018  if ((xx = rpmxarNext(xar)) != 0 || (xx = rpmxarPull(xar, item)) != 0) {
1019  rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item,
1020  _("XAR file not found (or no XAR support)"));
1021  rc = RPMRC_NOTFOUND;
1022  goto exit;
1023  }
1024  }
1025 
1026  /* Read the payload from the package. */
1027  while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), fd)) > 0)
1028  dig->nbytes += count;
1029  if (count < 0 || Ferror(fd)) {
1030  rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, _("Fread failed"), Fstrerror(fd));
1031  rc = RPMRC_FAIL;
1032  goto exit;
1033  }
1034 
1035  /* XXX Steal the digest-in-progress from the file handle. */
1036  fdStealDigest(fd, dig);
1037 
1038  rc = RPMRC_OK; /* XXX unnecessary */
1039 
1040 exit:
1041  return rc;
1042 }
1043 
1044 int rpmVerifySignatures(QVA_t qva, rpmts ts, void * _fd, const char * fn)
1045 {
1046  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
1047  HE_t she = (HE_t) memset(alloca(sizeof(*she)), 0, sizeof(*she));
1048 /*@-castexpose@*/
1049  FD_t fd = (FD_t)_fd;
1050 /*@=castexpose@*/
1051  char result[1024];
1052  char buf[8192], * b;
1053  char missingKeys[7164], * m;
1054  char untrustedKeys[7164], * u;
1055  pgpDig dig;
1057  Header sigh = NULL;
1058  HeaderIterator hi = NULL;
1059  int res = 0;
1060  int xx;
1061  rpmRC sigres;
1062  int failed;
1063  int nodigests = !(qva->qva_flags & VERIFY_DIGEST);
1064  int nosignatures = !(qva->qva_flags & VERIFY_SIGNATURE);
1065 pgpPkt pp = (pgpPkt) alloca(sizeof(*pp));
1066 
1067  {
1068  { const char item[] = "Lead";
1069  const char * msg = NULL;
1070  rpmRC rc = rpmpkgRead(item, fd, NULL, &msg);
1071  switch (rc) {
1072  default:
1073  rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item, msg);
1074  msg = _free(msg);
1075  res++;
1076  goto exit;
1077  /*@notreachea@*/ break;
1078  case RPMRC_OK:
1079  break;
1080  }
1081  msg = _free(msg);
1082  }
1083 
1084  { const char item[] = "Signature";
1085  const char * msg = NULL;
1086  rpmRC rc = rpmpkgRead(item, fd, &sigh, &msg);
1087  switch (rc) {
1088  default:
1089  rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item,
1090  (msg && *msg ? msg : ""));
1091  msg = _free(msg);
1092  res++;
1093  goto exit;
1094  /*@notreached@*/ /*@switchbreak@*/ break;
1095  case RPMRC_OK:
1096  if (sigh == NULL) {
1097  rpmlog(RPMLOG_ERR, _("%s: No signature available\n"), fn);
1098  res++;
1099  goto exit;
1100  }
1101  /*@switchbreak@*/ break;
1102  }
1103  msg = _free(msg);
1104  }
1105 
1106  /* Grab a hint of what needs doing to avoid duplication. */
1107  she->tag = (rpmTag)0;
1108  if (she->tag == 0 && !nosignatures) {
1109  if (headerIsEntry(sigh, (rpmTag) RPMSIGTAG_DSA))
1110  she->tag = (rpmTag) RPMSIGTAG_DSA;
1111  else if (headerIsEntry(sigh, (rpmTag) RPMSIGTAG_RSA))
1112  she->tag = (rpmTag) RPMSIGTAG_RSA;
1113  }
1114  if (she->tag == 0 && !nodigests) {
1115  if (headerIsEntry(sigh, (rpmTag) RPMSIGTAG_MD5))
1116  she->tag = (rpmTag) RPMSIGTAG_MD5;
1117  else if (headerIsEntry(sigh, (rpmTag) RPMSIGTAG_SHA1))
1118  she->tag = (rpmTag) RPMSIGTAG_SHA1; /* XXX never happens */
1119  }
1120 
1121  dig = rpmtsDig(ts);
1122 /*@-mods@*/ /* LCL: avoid void * _fd annotation for now. */
1123  (void) fdSetDig(fd, dig);
1124 /*@=mods@*/
1125  sigp = pgpGetSignature(dig);
1126 
1127  /* XXX RSA needs the hash_algo, so decode early. */
1128  if ((rpmSigTag) she->tag == RPMSIGTAG_RSA) {
1129  he->tag = she->tag;
1130  xx = headerGet(sigh, he, 0);
1131  xx = pgpPktLen(he->p.ui8p, he->c, pp);
1132  xx = rpmhkpLoadSignature(NULL, dig, pp);
1133  he->p.ptr = _free(he->p.ptr);
1134  }
1135 
1136 /*@-mods@*/ /* LCL: avoid void * _fd annotation for now. */
1137  if (headerIsEntry(sigh, (rpmTag)RPMSIGTAG_MD5))
1138  fdInitDigest(fd, PGPHASHALGO_MD5, 0);
1139 /*@=mods@*/
1140 
1141  /* Read the file, generating digest(s) on the fly. */
1142 /*@-mods@*/ /* LCL: avoid void * _fd annotation for now. */
1143  if (dig == NULL || sigp == NULL
1144  || readFile(fd, fn) != RPMRC_OK)
1145  {
1146  res++;
1147  goto exit;
1148  }
1149 /*@=mods@*/
1150 
1151  failed = 0;
1152  b = buf; *b = '\0';
1153  m = missingKeys; *m = '\0';
1154  u = untrustedKeys; *u = '\0';
1155  sprintf(b, "%s:%c", fn, (rpmIsVerbose() ? '\n' : ' ') );
1156  b += strlen(b);
1157 
1158  if (sigh != NULL)
1159  for (hi = headerInit(sigh);
1160  headerNext(hi, she, 0) != 0;
1161  she->p.ptr = _free(she->p.ptr))
1162  {
1163 
1164 assert(she->p.ptr != NULL);
1165 
1166  /* Clean up parameters from previous she->tag. */
1167  pgpDigClean(dig);
1168 
1169 /*@-ownedtrans -noeffect@*/
1170  xx = pgpSetSig(dig, she->tag, she->t, she->p.ptr, she->c);
1171 /*@=ownedtrans =noeffect@*/
1172 
1173  switch ((rpmSigTag)she->tag) {
1174  case RPMSIGTAG_RSA:
1175  case RPMSIGTAG_DSA:
1176  if (nosignatures)
1177  continue;
1178 
1179  xx = pgpPktLen(she->p.ui8p, she->c, pp);
1180  xx = rpmhkpLoadSignature(NULL, dig, pp);
1181  if (sigp->version != 3 && sigp->version != 4) {
1183  _("skipping package %s with unverifiable V%u signature\n"),
1184  fn, sigp->version);
1185  res++;
1186  goto exit;
1187  }
1188  /*@switchbreak@*/ break;
1189  case RPMSIGTAG_SHA1:
1190  if (nodigests)
1191  continue;
1192  /* XXX Don't bother with header sha1 if header dsa. */
1193  if (!nosignatures && (rpmSigTag)she->tag == RPMSIGTAG_DSA)
1194  continue;
1195  /*@switchbreak@*/ break;
1196  case RPMSIGTAG_MD5:
1197  if (nodigests)
1198  continue;
1199  /*@switchbreak@*/ break;
1200  default:
1201  continue;
1202  /*@notreached@*/ /*@switchbreak@*/ break;
1203  }
1204 
1205  sigres = rpmVerifySignature(dig, result);
1206 
1207  if (sigres) {
1208  failed = 1;
1209  if (rpmIsVerbose())
1210  b = stpcpy( stpcpy( stpcpy(b, " "), result), "\n");
1211  else
1212  switch ((rpmSigTag)she->tag) {
1213  case RPMSIGTAG_SIZE:
1214  b = stpcpy(b, "SIZE ");
1215  /*@switchbreak@*/ break;
1216  case RPMSIGTAG_SHA1:
1217  b = stpcpy(b, "SHA1 ");
1218  /*@switchbreak@*/ break;
1219  case RPMSIGTAG_MD5:
1220  b = stpcpy(b, "MD5 ");
1221  /*@switchbreak@*/ break;
1222  case RPMSIGTAG_RSA:
1223  b = stpcpy(b, "RSA ");
1224  /*@switchbreak@*/ break;
1225  case RPMSIGTAG_DSA:
1226  b = stpcpy(b, "(SHA1) DSA ");
1227  /*@switchbreak@*/ break;
1228  default:
1229  b = stpcpy(b, "?UnknownSignatureType? ");
1230  /*@switchbreak@*/ break;
1231  }
1232  } else {
1233  if (rpmIsVerbose())
1234  b = stpcpy( stpcpy( stpcpy(b, " "), result), "\n");
1235  else
1236  switch ((rpmSigTag)she->tag) {
1237  case RPMSIGTAG_SIZE:
1238  b = stpcpy(b, "size ");
1239  /*@switchbreak@*/ break;
1240  case RPMSIGTAG_SHA1:
1241  b = stpcpy(b, "sha1 ");
1242  /*@switchbreak@*/ break;
1243  case RPMSIGTAG_MD5:
1244  b = stpcpy(b, "md5 ");
1245  /*@switchbreak@*/ break;
1246  case RPMSIGTAG_RSA:
1247  b = stpcpy(b, "rsa ");
1248  /*@switchbreak@*/ break;
1249  case RPMSIGTAG_DSA:
1250  b = stpcpy(b, "(sha1) dsa ");
1251  /*@switchbreak@*/ break;
1252  default:
1253  b = stpcpy(b, "??? ");
1254  /*@switchbreak@*/ break;
1255  }
1256  }
1257  }
1258  hi = headerFini(hi);
1259  /* XXX clear the already free'd signature data. */
1260 /*@-noeffect@*/
1261  xx = pgpSetSig(dig, 0, 0, NULL, 0);
1262 /*@=noeffect@*/
1263 
1264  res += failed;
1265 
1266  if (failed) {
1267  if (rpmIsVerbose()) {
1268  rpmlog(RPMLOG_NOTICE, "%s", buf);
1269  } else {
1270  rpmlog(RPMLOG_NOTICE, "%s%s%s%s%s%s%s%s\n", buf,
1271  _("NOT_OK"),
1272  (missingKeys[0] != '\0') ? _(" (MISSING KEYS:") : "",
1273  missingKeys,
1274  (missingKeys[0] != '\0') ? _(") ") : "",
1275  (untrustedKeys[0] != '\0') ? _(" (UNTRUSTED KEYS:") : "",
1276  untrustedKeys,
1277  (untrustedKeys[0] != '\0') ? _(")") : "");
1278 
1279  }
1280  } else {
1281  if (rpmIsVerbose()) {
1282  rpmlog(RPMLOG_NOTICE, "%s", buf);
1283  } else {
1284  rpmlog(RPMLOG_NOTICE, "%s%s%s%s%s%s%s%s\n", buf,
1285  _("OK"),
1286  (missingKeys[0] != '\0') ? _(" (MISSING KEYS:") : "",
1287  missingKeys,
1288  (missingKeys[0] != '\0') ? _(") ") : "",
1289  (untrustedKeys[0] != '\0') ? _(" (UNTRUSTED KEYS:") : "",
1290  untrustedKeys,
1291  (untrustedKeys[0] != '\0') ? _(")") : "");
1292  }
1293  }
1294 
1295  }
1296 
1297 exit:
1298  rpmtsCleanDig(ts);
1299  (void)headerFree(sigh);
1300  sigh = NULL;
1301  return res;
1302 }
1303 
1304 int rpmcliSign(rpmts ts, QVA_t qva, const char ** argv)
1305  /*@globals rpmioFtsOpts @*/
1306  /*@modifies rpmioFtsOpts @*/
1307 {
1308  rpmRC rpmrc;
1309  int res = 0;
1310 
1311  if (argv == NULL) return res;
1312 
1313  switch (qva->qva_mode) {
1314  case RPMSIGN_CHK_SIGNATURE:
1315  break;
1316  case RPMSIGN_IMPORT_PUBKEY:
1317  return rpmcliImportPubkeys(ts, qva, argv);
1318  /*@notreached@*/ break;
1319  case RPMSIGN_NEW_SIGNATURE:
1320  case RPMSIGN_ADD_SIGNATURE:
1321  case RPMSIGN_DEL_SIGNATURE:
1322  return rpmReSign(ts, qva, argv);
1323  /*@notreached@*/ break;
1324  case RPMSIGN_NONE:
1325  default:
1326  return -1;
1327  /*@notreached@*/ break;
1328  }
1329 
1330 { /* start-of-arg-iteration */
1331 
1332  int tag = (qva->qva_source == RPMQV_FTSWALK)
1334  rpmgi gi = rpmgiNew(ts, tag, NULL, 0);
1335  rpmgiFlags _giFlags = RPMGI_NONE;
1336  rpmRC rc;
1337 
1338  if (rpmioFtsOpts == 0)
1340  rc = (rpmRC)
1341  rpmgiSetArgs(gi, argv, rpmioFtsOpts,
1342  (rpmgiFlags)(_giFlags|RPMGI_NOHEADER));
1343  while ((rpmrc = rpmgiNext(gi)) == RPMRC_OK) {
1344  const char * fn = rpmgiHdrPath(gi);
1345  FD_t fd;
1346  int xx;
1347 
1348  fd = Fopen(fn, "r.fdio");
1349  if (fd == NULL || Ferror(fd)) {
1350  rpmlog(RPMLOG_ERR, _("%s: open failed: %s\n"),
1351  fn, Fstrerror(fd));
1352  res++;
1353  } else if (rpmVerifySignatures(qva, ts, fd, fn)) {
1354  res++;
1355  }
1356 
1357  if (fd != NULL) {
1358  xx = Fclose(fd);
1359  }
1360  }
1361 
1362  /* XXX disambiguate end-of-iteration from item failures. */
1363  if (res == 0 && rpmrc == RPMRC_NOTFOUND) {
1364  rpmrc = (rpmRC) rpmgiRc(gi);
1365  if (rpmrc != RPMRC_OK)
1366  res++;
1367  }
1368 
1369  gi = rpmgiFree(gi);
1370 
1371 } /* end-of-arg-iteration */
1372 
1373  return res;
1374 }
Structure(s)and methods for a XAR archive wrapper format.
static void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int _flags)
Attach digest to fd.
rpmTagType t
Definition: rpmtag.h:502
const char * str
Definition: rpmtag.h:73
int xx
Definition: spec.c:744
rpmTag tag
Definition: rpmtag.h:501
int rpmgiRc(rpmgi gi)
Return current iteration item(s) exit code.
Definition: rpmgi.c:861
const char ** argv
Definition: rpmtag.h:75
Header headerNew(void)
Create new (empty) header instance.
Definition: header.c:180
struct rpmxar_s * rpmxar
Definition: rpmxar.h:14
int pgpGrabPkts(const rpmuint8_t *pkts, size_t pktlen, rpmuint8_t ***pppkts, int *pnpkts)
Return array of packet pointers.
Definition: rpmpgp.c:1306
DIGEST_CTX ctx
Definition: signature.c:785
#define headerFree(_h)
Definition: rpmtag.h:870
rpmlog(RPMLOG_ERR,"%s\n", buf)
int pgpPktLen(const rpmuint8_t *pkt, size_t pleft, pgpPkt pp)
Definition: rpmpgp.c:939
const char * RPMVERSION
Definition: misc.c:17
rpmRC rpmpkgWrite(const char *fn, FD_t fd, void *ptr, const char **msg)
Write item onto file descriptor.
Definition: pkgio.c:1665
size_t Fwrite(const void *buf, size_t size, size_t nmemb, FD_t fd)
fwrite(3) clone.
Definition: rpmio.c:2432
char * xstrdup(const char *str)
Definition: rpmmalloc.c:321
rpmuint32_t * ui32p
Definition: rpmtag.h:70
FD_t Fopen(const char *path, const char *_fmode)
fopen(3) clone.
Definition: rpmio.c:2831
rpmgi rpmgiFree(rpmgi gi)
Destroy a generalized iterator.
static int rpmcliImportPubkeys(const rpmts ts, QVA_t qva, const char **argv)
Import public key(s).
Definition: rpmchecksig.c:867
static char *size_t nb
fgets(3) analogue that reads \ continuations.
Definition: macro.c:409
int pgpPubkeyFingerprint(const rpmuint8_t *pkt, size_t pktlen, rpmuint8_t *keyid)
Print/parse an OpenPGP subtype packet.
Definition: rpmpgp.c:969
struct rpmts_s * rpmts
The RPM Transaction Set.
Definition: rpmtypes.h:14
int rc
Definition: poptALL.c:670
rpmdb rpmtsGetRdb(rpmts ts)
Get transaction set database handle.
Definition: pkgio.c:151
The Header data structure.
int rpmxarNext(rpmxar xar)
Iterate a xar archive instance.
Definition: rpmxar.c:128
rpmQueryFlags qva_flags
Definition: rpmcli.h:633
headerSprintfExtension rpmHeaderFormats
Table of query format extensions.
Definition: formats.c:305
FD_t fdLink(void *cookie, const char *msg)
static rpmRC readFile(FD_t fd, const char *fn)
Definition: rpmchecksig.c:934
pgpDig rpmtsDig(rpmts ts)
Get OpenPGP packet parameters, i.e.
Definition: pkgio.c:442
Header headerReload(Header h, rpmTag tag)
Convert header to on-disk representation, and then reload.
Definition: header.c:1314
fts m
Definition: rpmmtree.c:3827
enum rpmTag_e rpmTag
Definition: rpmtag.h:468
int Fflush(FD_t fd)
fflush(3) clone.
Definition: rpmio.c:2914
rpmiob rpmiobFree(rpmiob iob)
Destroy a I/O buffer instance.
Header tag iterator data structure.
Definition: header.c:2128
void pgpDigClean(pgpDig dig)
Release (malloc&#39;d) data from container.
Definition: rpmpgp.c:1106
rpmRC rpmcliImportPubkey(const rpmts ts, const unsigned char *pkt, ssize_t pktlen)
Import public key packet(s).
Definition: rpmchecksig.c:509
Header headerCopyLoad(const void *uh)
Make a copy and convert header to in-memory representation.
Definition: header.c:1432
int rpmdbAdd(rpmdb db, int iid, Header h, rpmts ts)
Add package header to rpm database and indices.
Definition: rpmdb.c:2883
rpmiob rpmiobAppend(rpmiob iob, const char *s, size_t nl)
Append string to I/O buffer.
Definition: rpmiob.c:77
Header headerLink(Header h)
Reference a header instance.
Header h
Definition: spec.c:739
rpmuint32_t rpmtsGetTid(rpmts ts)
Get transaction id, i.e.
Definition: rpmts.c:1022
argv
Definition: rpmmtree.c:3679
static int copyFile(FD_t *sfdp, const char **sfnp, FD_t *tfdp, const char **tfnp)
Copy header+payload, calculating digest(s) on the fly.
Definition: rpmchecksig.c:110
HeaderIterator headerInit(Header h)
Create header tag iterator.
Definition: header.c:2143
pid_t result
Definition: rpmsq.c:737
Command line option information.
Definition: rpmcli.h:630
struct pgpDig_s * pgpDig
Definition: rpmiotypes.h:86
unsigned char rpmuint8_t
Private int typedefs to avoid C99 portability issues.
Definition: rpmiotypes.h:26
static PyObject *char * mode
Definition: rpmfd-py.c:115
struct rpmiob_s * rpmiob
Definition: rpmiotypes.h:60
#define _fd(_a)
Definition: psm.h:32
sprintf(t," (%u)",(unsigned) dig->nbytes)
pgpArmor pgpReadPkts(const char *fn, rpmuint8_t **pkt, size_t *pktlen)
Parse armored OpenPGP packets from a file.
Definition: rpmpgp.c:1569
enum rpmSigTag_e rpmSigTag
Definition: rpmtag.h:472
rpmRC res
Definition: signature.c:584
char * alloca()
static int getSignid(Header sigh, rpmSigTag sigtag, unsigned char *signid)
Retrieve signer fingerprint from an OpenPGP signature tag.
Definition: rpmchecksig.c:159
pgpDig pgpDigNew(pgpVSFlags vsflags, pgpPubkeyAlgo pubkey_algo)
Create a container for parsed OpenPGP packates.
Definition: rpmpgp.c:1205
enum rpmRC_e rpmRC
RPM return codes.
Definition: signature.c:616
goto exit
Definition: db3.c:1903
memset(_r, 0, sizeof(*_r))
int count
Definition: rpmdb-py.c:157
int headerDel(Header h, HE_t he, unsigned int flags)
Remove tag container from header.
Definition: header.c:2312
unsigned int rpmuint32_t
Definition: rpmiotypes.h:28
const char * Fstrerror(FD_t fd)
strerror(3) clone.
Definition: rpmio.c:2399
assert(key->size==sizeof(hdrNum))
void * ptr
Definition: rpmtag.h:67
int _print_pkts
Definition: rpmchecksig.c:47
int ix
Definition: rpmps-py.c:174
int headerGetMagic(Header h, unsigned char **magicp, size_t *nmagicp)
Return header magic.
Definition: header.c:1162
char * headerSprintf(Header h, const char *fmt, headerTagTableEntry tags, headerSprintfExtension exts, errmsg_t *errmsg)
Return formatted output string from header tags.
Definition: hdrfmt.c:6748
rpmgi rpmgiNew(rpmts ts, int tag, const void *keyp, size_t keylen)
Return a generalized iterator.
Definition: rpmgi.c:543
int rpmAddSignature(Header sigh, const char *file, rpmSigTag sigTag, const char *passPhrase)
Generate signature(s) from a header+payload file, save in signature header.
Definition: signature.c:433
static char * pgpHexStr(const rpmuint8_t *p, size_t plen)
Return hex formatted representation of bytes.
Definition: rpmpgp.h:1164
int rpmxarPull(rpmxar xar, const char *fn)
Definition: rpmxar.c:168
struct _FD_s * FD_t
Definition: rpmio.h:43
int headerIsEntry(Header h, rpmTag tag)
Check if tag is in header.
Definition: header.c:1438
fprintf(stderr,"--> %s(%p,%p,%p) sig %p sigp %p\n", __FUNCTION__, dig, t, rsactx, sig, sigp)
FD_t fdFree(FD_t fd, const char *msg)
static rpmxar fdGetXAR(FD_t fd)
int Rename(const char *oldpath, const char *newpath)
rename(2) clone.
Definition: rpmrpc.c:286
enum rpmgiFlags_e rpmgiFlags
enum pgpHashAlgo_e pgpHashAlgo
9.4.
The lead data structure.
Definition: pkgio.c:480
int rpmTempFile(const char *prefix, const char **fnptr, void *fdptr)
Return file handle for a temporaray file.
Definition: signature.c:30
#define FTS_COMFOLLOW
Definition: fts.h:87
he tag
Definition: db3.c:1927
rpmTagData p
Definition: rpmtag.h:504
int rpmDigestUpdate(DIGEST_CTX ctx, const void *data, size_t len)
Update context with next plain text buffer.
Definition: digest.c:907
pgpDigParams pgpGetSignature(pgpDig dig)
Return OpenPGP signature parameters.
Definition: rpmpgp.c:1226
#define RPMDBI_FTSWALK
Definition: rpmtag.h:485
struct _HE_s * HE_t
Destroy an extension cache.
Definition: rpmtag.h:59
Digest private data.
Definition: digest.c:127
unsigned int pktlen
Definition: rpmts-py.c:1092
int headerGet(Header h, HE_t he, unsigned int flags)
Retrieve extension or tag value from a header.
Definition: header.c:2230
rpmRC rpmgiSetArgs(rpmgi gi, ARGV_t argv, int ftsOpts, rpmgiFlags flags)
Load iterator args.
Definition: rpmgi.c:866
rpmQVSources qva_source
Definition: rpmcli.h:631
The FD_t File Handle data structure.
int headerPut(Header h, HE_t he, unsigned int flags)
Add or append tag container to header.
Definition: header.c:2293
pgpDig pgpDigFree(pgpDig dig)
Destroy a container for parsed OpenPGP packates.
struct pgpPkt_s * pgpPkt
Definition: rpmiotypes.h:82
rpmTagCount c
Definition: rpmtag.h:505
Generate and verify rpm package signatures.
DIGEST_CTX rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags)
Initialize digest.
Definition: digest.c:244
int rpmioFtsOpts
Definition: poptIO.c:526
char * rpmExpand(const char *arg,...)
Return (malloc&#39;ed) concatenated macro expansion(s).
Definition: macro.c:3178
static void fdSetDig(FD_t fd, pgpDig dig)
int rpmtsOpenDB(rpmts ts, int dbmode)
Open the database used by the transaction.
Definition: rpmts.c:115
size_t Fread(void *buf, size_t size, size_t nmemb, FD_t fd)
fread(3) clone.
Definition: rpmio.c:2410
rpmRC rpmrc
Definition: rpmts-py.c:924
rpmuint8_t * ui8p
Definition: rpmtag.h:68
node fd
Definition: rpmfd-py.c:124
const char * passPhrase
Definition: rpmcli.h:655
int Fclose(FD_t fd)
fclose(3) clone.
Definition: rpmio.c:2532
char * n
Definition: macro.c:744
rpmiob rpmiobNew(size_t len)
Create an I/O buffer.
Definition: rpmiob.c:44
int headerNext(HeaderIterator hi, HE_t he, unsigned int flags)
Return next tag from header.
Definition: header.c:2157
fts u
Definition: rpmmtree.c:3828
#define RPMDBI_ARGLIST
Definition: rpmtag.h:484
int Ferror(FD_t fd)
ferror(3) clone.
Definition: rpmio.c:2942
Definition: rpmtag.h:500
void rpmtsClean(rpmts ts)
Free memory needed only for dependency checks and ordering.
Definition: rpmts.c:596
const char * s
Definition: poptALL.c:734
char * t
Definition: rpmds.c:2716
Methods to handle package elements.
static void fdStealDigest(FD_t fd, pgpDig dig)
char * stpcpy(char *dest, const char *src)
const char * SHA1
Definition: signature.c:684
void * headerUnload(Header h, size_t *lenp)
headerUnload.
Definition: header.c:648
size_t headerSizeof(Header h)
Return size of on-disk header representation in bytes.
Definition: header.c:266
Structures and prototypes used for an &quot;rpmts&quot; transaction set.
int flags
Definition: fnmatch.c:282
const char * msg
Definition: rpmts-py.c:976
struct pgpDigParams_s * pgpDigParams
Definition: rpmiotypes.h:90
#define FTS_LOGICAL
Definition: fts.h:88
#define rpmIsVerbose()
Definition: rpmcb.h:21
return NULL
Definition: poptALL.c:613
rpmRC rpmgiNext(rpmgi gi)
Perform next iteration step.
Definition: rpmgi.c:584
int rpmcliSign(rpmts ts, QVA_t qva, const char **argv)
Create/Modify/Check elements from signature header.
Definition: rpmchecksig.c:1304
static void
Print copy of spec file, filling in Group/Description/Summary from specspo.
Definition: spec.c:737
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:1256
char * buf
Parse (and execute) macro undefinition.
Definition: macro.c:703
static int rpmReSign(rpmts ts, QVA_t qva, const char **argv)
Create/modify elements in signature header.
Definition: rpmchecksig.c:193
static PyObject *unsigned char * pkt
Definition: rpmts-py.c:1089
#define _(Text)
Definition: system.h:29
const char * rpmgiHdrPath(rpmgi gi)
Return current header path.
Definition: rpmgi.c:842
char * b
Definition: macro.c:746
int
Save source and expand field into target.
Definition: rpmds.c:2709
#define xmalloc
Definition: system.h:32
void rpmDigestFinal(rpmDigestDup(md5ctx),&md5sum,&md5len, 0)
rpmRC rpmpkgRead(const char *fn, FD_t fd, void *ptr, const char **msg)
Read item from file descriptor.
Definition: pkgio.c:1647
Access RPM indices using Berkeley DB interface(s).
static int manageFile(FD_t *fdp, const char **fnp, int flags, int rc)
Definition: rpmchecksig.c:51
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:647
pgpDigParams sigp
Definition: signature.c:748
int i
Definition: spec.c:743
pgpDig dig
Definition: rpmts-py.c:979
#define FTS_NOSTAT
Definition: fts.h:90
pgpArmor pgpArmorUnwrap(rpmiob iob, rpmuint8_t **pkt, size_t *pktlen)
Parse armored OpenPGP packets from an iob.
Definition: rpmpgp.c:1398
static pgpDig fdGetDig(FD_t fd)
rpmRC rpmVerifySignature(void *_dig, char *result)
Verify a signature from a package.
Definition: signature.c:941
struct rpmgi_s * rpmgi
Generalized iterator.
Definition: rpmtypes.h:53
pgpDigParams pgpGetPubkey(pgpDig dig)
Return OpenPGP pubkey parameters.
Definition: rpmpgp.c:1231
size_t fn
Definition: macro.c:1698
int rpmVerifySignatures(QVA_t qva, rpmts ts, void *_fd, const char *fn)
Check package and header signatures.
Definition: rpmchecksig.c:1044
HeaderIterator headerFini(HeaderIterator hi)
Destroy header tag container iterator.
Definition: header.c:2133
unsigned int append
Definition: rpmtag.h:509
int Unlink(const char *path)
unlink(2) clone.
Definition: rpmrpc.c:397
void rpmtsCleanDig(rpmts ts)
Free signature verification data.
Definition: pkgio.c:457