|
rpm
5.4.4
|
00001 00006 #include "system.h" 00007 00008 #include <rpmio_internal.h> 00009 #include <poptIO.h> 00010 #include <rpmbc.h> /* XXX beecrypt base64 */ 00011 00012 #define _RPMHKP_INTERNAL /* XXX internal prototypes. */ 00013 #include <rpmhkp.h> 00014 00015 #include <rpmtag.h> 00016 #include <rpmtypes.h> 00017 #define _RPMEVR_INTERNAL /* XXX RPMSENSE_KEYRING */ 00018 #include <rpmevr.h> 00019 #define _RPMDB_INTERNAL /* XXX db_txn */ 00020 #include <rpmdb.h> 00021 #include <rpmtxn.h> 00022 #include <rpmxar.h> 00023 #include <pkgio.h> 00024 #include "signature.h" 00025 00026 #define _RPMTS_INTERNAL /* XXX ts->hkp */ 00027 #include <rpmts.h> 00028 00029 #include "rpmgi.h" 00030 00031 #include <rpmversion.h> 00032 #include <rpmcli.h> 00033 00034 #include "debug.h" 00035 00036 /*@access FD_t @*/ /* XXX stealing digests */ 00037 /*@access Header @*/ /* XXX void * arg */ 00038 /*@access pgpDig @*/ 00039 /*@access pgpDigParams @*/ 00040 00041 /*@unchecked@*/ 00042 int _print_pkts = 0; 00043 00046 static int manageFile(/*@out@*/ FD_t *fdp, 00047 /*@null@*/ /*@out@*/ const char **fnp, 00048 int flags, /*@unused@*/ int rc) 00049 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/ 00050 /*@modifies *fdp, *fnp, rpmGlobalMacroContext, 00051 fileSystem, internalState @*/ 00052 { 00053 const char *fn; 00054 FD_t fd; 00055 00056 if (fdp == NULL) /* programmer error */ 00057 return 1; 00058 00059 /* close and reset *fdp to NULL */ 00060 if (*fdp && (fnp == NULL || *fnp == NULL)) { 00061 (void) Fclose(*fdp); 00062 *fdp = NULL; 00063 return 0; 00064 } 00065 00066 /* open a file and set *fdp */ 00067 if (*fdp == NULL && fnp != NULL && *fnp != NULL) { 00068 fd = Fopen(*fnp, ((flags & O_WRONLY) ? "w.fdio" : "r.fdio")); 00069 if (fd == NULL || Ferror(fd)) { 00070 rpmlog(RPMLOG_ERR, _("%s: open failed: %s\n"), *fnp, 00071 Fstrerror(fd)); 00072 return 1; 00073 } 00074 *fdp = fd; 00075 return 0; 00076 } 00077 00078 /* open a temp file */ 00079 if (*fdp == NULL && (fnp == NULL || *fnp == NULL)) { 00080 fn = NULL; 00081 if (rpmTempFile(NULL, (fnp ? &fn : NULL), &fd)) { 00082 rpmlog(RPMLOG_ERR, _("rpmTempFile failed\n")); 00083 return 1; 00084 } 00085 if (fnp != NULL) 00086 *fnp = fn; 00087 /*@-refcounttrans@*/ /* FIX: XfdLink/XfdFree annotation */ 00088 *fdp = fdLink(fd, "manageFile return"); 00089 fd = fdFree(fd, "manageFile return"); 00090 /*@=refcounttrans@*/ 00091 return 0; 00092 } 00093 00094 /* no operation */ 00095 if (*fdp != NULL && fnp != NULL && *fnp != NULL) 00096 return 0; 00097 00098 /* XXX never reached */ 00099 return 1; 00100 } 00101 00105 static int copyFile(FD_t *sfdp, const char **sfnp, 00106 FD_t *tfdp, const char **tfnp) 00107 /*@globals rpmGlobalMacroContext, h_errno, 00108 fileSystem, internalState @*/ 00109 /*@modifies *sfdp, *sfnp, *tfdp, *tfnp, rpmGlobalMacroContext, 00110 fileSystem, internalState @*/ 00111 { 00112 unsigned char buf[BUFSIZ]; 00113 ssize_t count; 00114 int rc = 1; 00115 00116 if (manageFile(sfdp, sfnp, O_RDONLY, 0)) 00117 goto exit; 00118 if (manageFile(tfdp, tfnp, O_WRONLY|O_CREAT|O_TRUNC, 0)) 00119 goto exit; 00120 00121 while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), *sfdp)) > 0) 00122 { 00123 if (Fwrite(buf, sizeof(buf[0]), count, *tfdp) != (size_t)count) { 00124 rpmlog(RPMLOG_ERR, _("%s: Fwrite failed: %s\n"), *tfnp, 00125 Fstrerror(*tfdp)); 00126 goto exit; 00127 } 00128 } 00129 if (count < 0) { 00130 rpmlog(RPMLOG_ERR, _("%s: Fread failed: %s\n"), *sfnp, Fstrerror(*sfdp)); 00131 goto exit; 00132 } 00133 if (Fflush(*tfdp) != 0) { 00134 rpmlog(RPMLOG_ERR, _("%s: Fflush failed: %s\n"), *tfnp, 00135 Fstrerror(*tfdp)); 00136 goto exit; 00137 } 00138 00139 rc = 0; 00140 00141 exit: 00142 if (*sfdp) (void) manageFile(sfdp, NULL, 0, rc); 00143 if (*tfdp) (void) manageFile(tfdp, NULL, 0, rc); 00144 return rc; 00145 } 00146 00154 static int getSignid(Header sigh, rpmSigTag sigtag, unsigned char * signid) 00155 /*@globals fileSystem, internalState @*/ 00156 /*@modifies *signid, fileSystem, internalState @*/ 00157 { 00158 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); 00159 int rc = 1; 00160 int xx; 00161 00162 he->tag = (rpmTag) sigtag; 00163 xx = headerGet(sigh, he, 0); 00164 if (xx && he->p.ptr != NULL) { 00165 pgpDig dig = pgpDigNew(RPMVSF_DEFAULT, 0); 00166 00167 /* XXX expose ppSignid() from rpmhkp.c? */ 00168 pgpPkt pp = alloca(sizeof(*pp)); 00169 (void) pgpPktLen(he->p.ptr, he->c, pp); 00170 if (!rpmhkpLoadSignature(NULL, dig, pp)) { 00171 memcpy(signid, dig->signature.signid, sizeof(dig->signature.signid)); 00172 rc = 0; 00173 } 00174 00175 he->p.ptr = _free(he->p.ptr); 00176 dig = pgpDigFree(dig); 00177 } 00178 return rc; 00179 } 00180 00188 static int rpmReSign(/*@unused@*/ rpmts ts, 00189 QVA_t qva, const char ** argv) 00190 /*@globals rpmGlobalMacroContext, h_errno, 00191 fileSystem, internalState @*/ 00192 /*@modifies ts, rpmGlobalMacroContext, 00193 fileSystem, internalState @*/ 00194 { 00195 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); 00196 rpmgi gi = NULL; 00197 FD_t fd = NULL; 00198 FD_t ofd = NULL; 00199 struct rpmlead *lead = NULL; 00200 rpmSigTag sigtag; 00201 const char *sigtarget = NULL; 00202 char tmprpm[1024+1]; 00203 Header sigh = NULL; 00204 int res = 1; /* XXX assume failure */ 00205 int deleting = (qva->qva_mode == RPMSIGN_DEL_SIGNATURE); 00206 rpmRC rpmrc = 0; 00207 int xx; 00208 int i; 00209 mode_t mode; 00210 00211 tmprpm[0] = '\0'; 00212 00213 if (argv) 00214 { /* start-of-arg-iteration */ 00215 rpmuint32_t tag = (qva->qva_source == RPMQV_FTSWALK) 00216 ? RPMDBI_FTSWALK : RPMDBI_ARGLIST; 00217 rpmgiFlags _giFlags = RPMGI_NONE; 00218 00219 gi = rpmgiNew(ts, tag, NULL, 0); 00220 /*@-mods@*/ 00221 if (rpmioFtsOpts == 0) 00222 rpmioFtsOpts = (FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOSTAT); 00223 /*@=mods@*/ 00224 rpmrc = rpmgiSetArgs(gi, argv, rpmioFtsOpts, (_giFlags|RPMGI_NOHEADER)); 00225 00226 while ((rpmrc = rpmgiNext(gi)) == RPMRC_OK) { 00227 const char * fn = rpmgiHdrPath(gi); 00228 const char * tfn; 00229 00230 fprintf(stdout, "%s:\n", fn); 00231 00232 /*@-modobserver@*/ /* XXX rpmgiHdrPath should not be observer */ 00233 if (manageFile(&fd, &fn, O_RDONLY, 0)) 00234 goto exit; 00235 /*@=modobserver@*/ 00236 00237 { const char item[] = "Lead"; 00238 const char * msg = NULL; 00239 rpmRC rc = rpmpkgRead(item, fd, &lead, &msg); 00240 if (rc != RPMRC_OK) { 00241 rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item, msg); 00242 msg = _free(msg); 00243 goto exit; 00244 } 00245 msg = _free(msg); 00246 } 00247 00248 { const char item[] = "Signature"; 00249 const char * msg = NULL; 00250 rpmRC rc = rpmpkgRead(item, fd, &sigh, &msg); 00251 switch (rc) { 00252 default: 00253 rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item, 00254 (msg && *msg ? msg : "")); 00255 msg = _free(msg); 00256 goto exit; 00257 /*@notreached@*/ /*@switchbreak@*/ break; 00258 case RPMRC_OK: 00259 if (sigh == NULL) { 00260 rpmlog(RPMLOG_ERR, _("%s: No signature available\n"), fn); 00261 goto exit; 00262 } 00263 /*@switchbreak@*/ break; 00264 } 00265 msg = _free(msg); 00266 } 00267 00268 /* Write the header and archive to a temp file */ 00269 /* ASSERT: ofd == NULL && sigtarget == NULL */ 00270 /*@-modobserver@*/ /* XXX rpmgiHdrPath should not be observer */ 00271 if (copyFile(&fd, &fn, &ofd, &sigtarget)) 00272 goto exit; 00273 /*@=modobserver@*/ 00274 /* Both fd and ofd are now closed. sigtarget contains tempfile name. */ 00275 /* ASSERT: fd == NULL && ofd == NULL */ 00276 00277 /* Lose the immutable region (if present). */ 00278 he->tag = RPMTAG_HEADERSIGNATURES; 00279 xx = headerGet(sigh, he, 0); 00280 if (xx) { 00281 HE_t ohe = memset(alloca(sizeof(*ohe)), 0, sizeof(*ohe)); 00282 HeaderIterator hi; 00283 Header oh; 00284 Header nh; 00285 00286 nh = headerNew(); 00287 if (nh == NULL) { 00288 he->p.ptr = _free(he->p.ptr); 00289 goto exit; 00290 } 00291 00292 oh = headerCopyLoad(he->p.ptr); 00293 for (hi = headerInit(oh); 00294 headerNext(hi, ohe, 0); 00295 ohe->p.ptr = _free(ohe->p.ptr)) 00296 { 00297 if (ohe->p.ptr) { 00298 xx = headerPut(nh, ohe, 0); 00299 } 00300 } 00301 hi = headerFini(hi); 00302 (void)headerFree(oh); 00303 oh = NULL; 00304 00305 (void)headerFree(sigh); 00306 sigh = NULL; 00307 sigh = headerLink(nh); 00308 (void)headerFree(nh); 00309 nh = NULL; 00310 } 00311 00312 if (sigh != NULL) { 00313 /* Eliminate broken digest values. */ 00314 he->tag = (rpmTag)RPMSIGTAG_LEMD5_1; 00315 xx = headerDel(sigh, he, 0); 00316 he->tag = (rpmTag)RPMSIGTAG_LEMD5_2; 00317 xx = headerDel(sigh, he, 0); 00318 he->tag = (rpmTag)RPMSIGTAG_BADSHA1_1; 00319 xx = headerDel(sigh, he, 0); 00320 he->tag = (rpmTag)RPMSIGTAG_BADSHA1_2; 00321 xx = headerDel(sigh, he, 0); 00322 00323 /* Toss and recalculate header+payload size and digests. */ 00324 { static const rpmuint32_t sigs[] = 00325 { RPMSIGTAG_SIZE, RPMSIGTAG_MD5, RPMSIGTAG_SHA1 }; 00326 size_t nsigs = sizeof(sigs) / sizeof(sigs[0]); 00327 for (i = 0; i < (int)nsigs; i++) { 00328 he->tag = (rpmTag)sigs[i]; 00329 xx = headerDel(sigh, he, 0); 00330 xx = rpmAddSignature(sigh, sigtarget, (rpmSigTag) he->tag, qva->passPhrase); 00331 if (xx) 00332 goto exit; 00333 } 00334 } 00335 00336 if (deleting) { 00337 /* Nuke all the signature tags. */ 00338 static const rpmuint32_t sigs[] = 00339 { RPMSIGTAG_GPG, RPMSIGTAG_PGP5, RPMSIGTAG_PGP, 00340 RPMSIGTAG_DSA, RPMSIGTAG_RSA }; 00341 size_t nsigs = sizeof(sigs) / sizeof(sigs[0]); 00342 for (i = 0; i < (int)nsigs; i++) { 00343 he->tag = (rpmTag)sigs[i]; 00344 xx = headerDel(sigh, he, 0); 00345 } 00346 } else { /* If gpg/pgp is configured, replace the signature. */ 00347 int addsig = 0; 00348 sigtag = RPMSIGTAG_GPG; 00349 addsig = 1; 00350 00351 if (addsig) { 00352 unsigned char oldsignid[8], newsignid[8]; 00353 00354 /* Grab the old signature fingerprint (if any) */ 00355 memset(oldsignid, 0, sizeof(oldsignid)); 00356 xx = getSignid(sigh, sigtag, oldsignid); 00357 00358 switch (sigtag) { 00359 default: 00360 /*@switchbreak@*/ break; 00361 case RPMSIGTAG_DSA: 00362 he->tag = (rpmTag)RPMSIGTAG_GPG; 00363 xx = headerDel(sigh, he, 0); 00364 /*@switchbreak@*/ break; 00365 case RPMSIGTAG_RSA: 00366 he->tag = (rpmTag)RPMSIGTAG_PGP; 00367 xx = headerDel(sigh, he, 0); 00368 /*@switchbreak@*/ break; 00369 case RPMSIGTAG_GPG: 00370 he->tag = (rpmTag)RPMSIGTAG_PGP; 00371 xx = headerDel(sigh, he, 0); 00372 he->tag = (rpmTag)RPMSIGTAG_DSA; 00373 xx = headerDel(sigh, he, 0); 00374 /*@fallthrough@*/ 00375 case RPMSIGTAG_PGP5: 00376 case RPMSIGTAG_PGP: 00377 he->tag = (rpmTag)RPMSIGTAG_RSA; 00378 xx = headerDel(sigh, he, 0); 00379 /*@switchbreak@*/ break; 00380 } 00381 00382 he->tag = (rpmTag)sigtag; 00383 xx = headerDel(sigh, he, 0); 00384 xx = rpmAddSignature(sigh, sigtarget, sigtag, qva->passPhrase); 00385 if (xx) 00386 goto exit; 00387 00388 /* If package was previously signed, check for same signer. */ 00389 memset(newsignid, 0, sizeof(newsignid)); 00390 if (memcmp(oldsignid, newsignid, sizeof(oldsignid))) { 00391 00392 /* Grab the new signature fingerprint */ 00393 xx = getSignid(sigh, sigtag, newsignid); 00394 00395 /* If same signer, skip resigning the package. */ 00396 if (!memcmp(oldsignid, newsignid, sizeof(oldsignid))) { 00397 00398 rpmlog(RPMLOG_WARNING, 00399 _("%s: was already signed by key ID %s, skipping\n"), 00400 fn, pgpHexStr(newsignid+4, sizeof(newsignid)-4)); 00401 00402 /* Clean up intermediate target */ 00403 xx = Unlink(sigtarget); 00404 sigtarget = _free(sigtarget); 00405 continue; 00406 } 00407 } 00408 } 00409 } 00410 00411 /* Reallocate the signature into one contiguous region. */ 00412 sigh = headerReload(sigh, RPMTAG_HEADERSIGNATURES); 00413 if (sigh == NULL) /* XXX can't happen */ 00414 goto exit; 00415 } 00416 00417 /* Write the lead/signature of the output rpm */ 00418 (void) stpcpy( stpcpy(tmprpm, fn), ".XXXXXX"); 00419 00420 #if defined(HAVE_MKSTEMP) 00421 mode = umask(0077); 00422 (void) close(mkstemp(tmprpm)); 00423 (void) umask(mode); 00424 #else 00425 (void) mktemp(tmprpm); 00426 #endif 00427 tfn = tmprpm; 00428 00429 if (manageFile(&ofd, &tfn, O_WRONLY|O_CREAT|O_TRUNC, 0)) 00430 goto exit; 00431 00432 { const char item[] = "Lead"; 00433 const char * msg = NULL; 00434 rpmRC rc = rpmpkgWrite(item, ofd, lead, &msg); 00435 if (rc != RPMRC_OK) { 00436 rpmlog(RPMLOG_ERR, "%s: %s: %s\n", tfn, item, Fstrerror(ofd)); 00437 msg = _free(msg); 00438 goto exit; 00439 } 00440 msg = _free(msg); 00441 } 00442 00443 { const char item[] = "Signature"; 00444 const char * msg = NULL; 00445 rpmRC rc = rpmpkgWrite(item, ofd, sigh, &msg); 00446 if (rc != RPMRC_OK) { 00447 rpmlog(RPMLOG_ERR, "%s: %s: %s\n", tfn, item, Fstrerror(ofd)); 00448 msg = _free(msg); 00449 goto exit; 00450 } 00451 msg = _free(msg); 00452 } 00453 (void)headerFree(sigh); 00454 sigh = NULL; 00455 00456 /* Append the header and archive from the temp file */ 00457 /* ASSERT: fd == NULL && ofd != NULL */ 00458 if (copyFile(&fd, &sigtarget, &ofd, &tfn)) 00459 goto exit; 00460 /* Both fd and ofd are now closed. */ 00461 /* ASSERT: fd == NULL && ofd == NULL */ 00462 00463 /* Move final target into place. */ 00464 xx = Unlink(fn); 00465 xx = Rename(tfn, fn); 00466 tmprpm[0] = '\0'; 00467 00468 /* Clean up intermediate target */ 00469 xx = Unlink(sigtarget); 00470 sigtarget = _free(sigtarget); 00471 } 00472 00473 /* XXX disambiguate end-of-iteration from item failures. */ 00474 if (rpmrc == RPMRC_NOTFOUND) 00475 rpmrc = rpmgiRc(gi); 00476 00477 gi = rpmgiFree(gi); 00478 00479 } /* end-of-arg-iteration */ 00480 00481 if (rpmrc == RPMRC_OK) 00482 res = 0; 00483 00484 exit: 00485 if (fd) (void) manageFile(&fd, NULL, 0, res); 00486 if (ofd) (void) manageFile(&ofd, NULL, 0, res); 00487 00488 lead = _free(lead); 00489 (void)headerFree(sigh); 00490 sigh = NULL; 00491 00492 if (sigtarget) { 00493 xx = Unlink(sigtarget); 00494 sigtarget = _free(sigtarget); 00495 } 00496 if (tmprpm[0] != '\0') { 00497 xx = Unlink(tmprpm); 00498 tmprpm[0] = '\0'; 00499 } 00500 00501 return res; 00502 } 00503 00504 rpmRC rpmcliImportPubkey(const rpmts ts, const unsigned char * pkt, ssize_t pktlen) 00505 { 00506 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); 00507 static unsigned char zeros[] = 00508 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 00509 const char * afmt = "%{pubkeys:armor}"; 00510 const char * group = "Public Keys"; 00511 const char * license = "pubkey"; 00512 const char * buildhost = "localhost"; 00513 rpmuint32_t pflags = (RPMSENSE_KEYRING|RPMSENSE_EQUAL); 00514 rpmuint32_t zero = 0; 00515 pgpDig dig = NULL; 00516 pgpDigParams pubp = NULL; 00517 const char * d = NULL; 00518 const char * enc = NULL; 00519 const char * n = NULL; 00520 const char * u = NULL; 00521 const char * v = NULL; 00522 const char * r = NULL; 00523 const char * evr = NULL; 00524 Header h = NULL; 00525 rpmRC rc = RPMRC_FAIL; /* assume failure */ 00526 char * t; 00527 int xx; 00528 rpmhkp hkp = NULL; 00529 pgpPkt pp = alloca(sizeof(*pp)); 00530 int validate = 1; 00531 00532 if (pkt == NULL || pktlen <= 0) 00533 goto exit; 00534 if (rpmtsOpenDB(ts, (O_RDWR|O_CREAT))) 00535 goto exit; 00536 00537 /*@-moduncon@*/ 00538 if ((enc = b64encode(pkt, pktlen)) == NULL) 00539 goto exit; 00540 /*@=moduncon@*/ 00541 00542 dig = pgpDigNew(RPMVSF_DEFAULT, 0); 00543 pubp = pgpGetPubkey(dig); 00544 00545 //* Validate the pubkey. */ 00546 if (ts->hkp == NULL) 00547 ts->hkp = rpmhkpNew(NULL, 0); 00548 hkp = rpmhkpLink(ts->hkp); 00549 hkp->pkt = (rpmuint8_t *)pkt; 00550 hkp->pktlen = pktlen; 00551 00552 xx = pgpGrabPkts(hkp->pkt, hkp->pktlen, &hkp->pkts, &hkp->npkts); 00553 if (!xx) 00554 (void) pgpPubkeyFingerprint(hkp->pkt, hkp->pktlen, hkp->keyid); 00555 memcpy(pubp->signid, hkp->keyid, sizeof(pubp->signid)); /* XXX useless */ 00556 00557 xx = pgpPktLen(hkp->pkt, hkp->pktlen, pp); 00558 00559 xx = rpmhkpLoadKey(hkp, dig, 0, 0); 00560 00561 /* Validate pubkey self-signatures. */ 00562 if (validate) { 00563 rpmRC yy = rpmhkpValidate(hkp, NULL); 00564 switch (yy) { 00565 case RPMRC_OK: 00566 break; 00567 case RPMRC_NOTFOUND: 00568 case RPMRC_FAIL: /* XXX remap to NOTFOUND? */ 00569 case RPMRC_NOTTRUSTED: 00570 case RPMRC_NOKEY: 00571 default: 00572 #ifdef NOTYET /* XXX make check-pubkey fails?!? . */ 00573 rc = yy; 00574 goto exit; 00575 #endif 00576 /*@notreached@*/ break; 00577 } 00578 } 00579 00580 /* XXX hack up a user id (if not already present) */ 00581 if (pubp->userid == NULL) { 00582 if (hkp->uidx >= 0 && hkp->uidx < hkp->npkts) { 00583 size_t nb = pgpPktLen(hkp->pkts[hkp->uidx], hkp->pktlen, pp); 00584 char * t; 00585 nb = pp->hlen; 00586 t = memcpy(xmalloc(nb + 1), pp->u.u->userid, nb); 00587 t[nb] = '\0'; 00588 pubp->userid = t; 00589 } else 00590 pubp->userid = xstrdup(pgpHexStr(pubp->signid+4, 4)); 00591 } 00592 00593 #ifdef DYING 00594 _rpmhkpDumpDig(__FUNCTION__, dig); 00595 #endif 00596 00597 /* Build header elements. */ 00598 if (!memcmp(pubp->signid, zeros, sizeof(pubp->signid)) 00599 || !memcmp(pubp->time, zeros, sizeof(pubp->time)) 00600 || pubp->userid == NULL) 00601 goto exit; 00602 00603 v = t = xmalloc(16+1); 00604 t = stpcpy(t, pgpHexStr(pubp->signid, sizeof(pubp->signid))); 00605 00606 r = t = xmalloc(8+1); 00607 t = stpcpy(t, pgpHexStr(pubp->time, sizeof(pubp->time))); 00608 00609 n = t = xmalloc(sizeof("gpg()")+8); 00610 t = stpcpy( stpcpy( stpcpy(t, "gpg("), v+8), ")"); 00611 00612 { const char * userid = 00613 (pubp->userid ? pubp->userid : pgpHexStr(pubp->signid+4, 4)); 00614 u = t = xmalloc(sizeof("gpg()")+strlen(userid)); 00615 t = stpcpy( stpcpy( stpcpy(t, "gpg("), userid), ")"); 00616 } 00617 00618 evr = t = xmalloc(sizeof("4X:-")+strlen(v)+strlen(r)); 00619 t = stpcpy(t, (pubp->version == 4 ? "4:" : "3:")); 00620 t = stpcpy( stpcpy( stpcpy(t, v), "-"), r); 00621 00622 /* Check for pre-existing header. */ 00623 00624 /* Build pubkey header. */ 00625 h = headerNew(); 00626 00627 he->append = 1; 00628 00629 he->tag = RPMTAG_PUBKEYS; 00630 he->t = RPM_STRING_ARRAY_TYPE; 00631 he->p.argv = &enc; 00632 he->c = 1; 00633 xx = headerPut(h, he, 0); 00634 00635 he->append = 0; 00636 00637 d = headerSprintf(h, afmt, NULL, rpmHeaderFormats, NULL); 00638 if (d == NULL) 00639 goto exit; 00640 00641 he->t = RPM_STRING_TYPE; 00642 he->c = 1; 00643 he->tag = RPMTAG_NAME; 00644 he->p.str = xstrdup("gpg-pubkey"); 00645 xx = headerPut(h, he, 0); 00646 he->p.ptr = _free(he->p.ptr); 00647 he->tag = RPMTAG_VERSION; 00648 he->p.str = v+8; 00649 xx = headerPut(h, he, 0); 00650 he->tag = RPMTAG_RELEASE; 00651 he->p.str = xstrdup(r); 00652 xx = headerPut(h, he, 0); 00653 he->p.ptr = _free(he->p.ptr); 00654 00655 /* Add Summary/Description/Group. */ 00656 he->tag = RPMTAG_DESCRIPTION; 00657 he->p.str = xstrdup(d); 00658 #if defined(SUPPORT_IMPLICIT_TAG_DATA_TYPES) 00659 xx = headerAddI18NString(h, he->tag, he->p.ptr, "C"); 00660 #else 00661 xx = headerPut(h, he, 0); 00662 #endif 00663 he->p.ptr = _free(he->p.ptr); 00664 00665 he->tag = RPMTAG_GROUP; 00666 he->p.str = xstrdup(group); 00667 #if defined(SUPPORT_IMPLICIT_TAG_DATA_TYPES) 00668 xx = headerAddI18NString(h, he->tag, he->p.ptr, "C"); 00669 #else 00670 xx = headerPut(h, he, 0); 00671 #endif 00672 he->p.ptr = _free(he->p.ptr); 00673 00674 he->tag = RPMTAG_SUMMARY; 00675 he->p.str = xstrdup(u); 00676 #if defined(SUPPORT_IMPLICIT_TAG_DATA_TYPES) 00677 xx = headerAddI18NString(h, he->tag, he->p.ptr, "C"); 00678 #else 00679 xx = headerPut(h, he, 0); 00680 #endif 00681 he->p.ptr = _free(he->p.ptr); 00682 00683 #ifdef NOTYET /* XXX can't erase pubkeys with "pubkey" arch. */ 00684 /* Add a "pubkey" arch/os to avoid missing value NULL ptrs. */ 00685 he->tag = RPMTAG_ARCH; 00686 he->p.str = "pubkey"; 00687 xx = headerPut(h, he, 0); 00688 he->tag = RPMTAG_OS; 00689 he->p.str = "pubkey"; 00690 xx = headerPut(h, he, 0); 00691 #endif 00692 00693 he->tag = RPMTAG_LICENSE; 00694 he->p.str = xstrdup(license); 00695 xx = headerPut(h, he, 0); 00696 he->p.ptr = _free(he->p.ptr); 00697 00698 he->tag = RPMTAG_SIZE; 00699 he->t = RPM_UINT32_TYPE; 00700 he->p.ui32p = &zero; 00701 he->c = 1; 00702 xx = headerPut(h, he, 0); 00703 00704 he->append = 1; 00705 00706 /* Provides: gpg(IDENTITY) = PUBKEYVERSIONTYPE:PUBKEYID-CREATION */ 00707 he->tag = RPMTAG_PROVIDENAME; 00708 he->t = RPM_STRING_ARRAY_TYPE; 00709 he->p.argv = &u; 00710 he->c = 1; 00711 xx = headerPut(h, he, 0); 00712 he->tag = RPMTAG_PROVIDEVERSION; 00713 he->t = RPM_STRING_ARRAY_TYPE; 00714 he->p.argv = &evr; 00715 he->c = 1; 00716 xx = headerPut(h, he, 0); 00717 he->tag = RPMTAG_PROVIDEFLAGS; 00718 he->t = RPM_UINT32_TYPE; 00719 he->p.ui32p = &pflags; 00720 he->c = 1; 00721 xx = headerPut(h, he, 0); 00722 00723 /* Provides: gpg(PUBKEYID) = PUBKEYVERSION:PUBKEYID-CREATION */ 00724 he->tag = RPMTAG_PROVIDENAME; 00725 he->t = RPM_STRING_ARRAY_TYPE; 00726 he->p.argv = &n; 00727 he->c = 1; 00728 xx = headerPut(h, he, 0); 00729 he->tag = RPMTAG_PROVIDEVERSION; 00730 he->t = RPM_STRING_ARRAY_TYPE; 00731 he->p.argv = &evr; 00732 he->c = 1; 00733 xx = headerPut(h, he, 0); 00734 he->tag = RPMTAG_PROVIDEFLAGS; 00735 he->t = RPM_UINT32_TYPE; 00736 he->p.ui32p = &pflags; 00737 he->c = 1; 00738 xx = headerPut(h, he, 0); 00739 00740 he->append = 0; 00741 00742 he->tag = RPMTAG_RPMVERSION; 00743 he->t = RPM_STRING_TYPE; 00744 he->p.str = xstrdup(RPMVERSION); 00745 he->c = 1; 00746 xx = headerPut(h, he, 0); 00747 he->p.ptr = _free(he->p.ptr); 00748 00749 /* XXX W2DO: tag value inherited from parent? */ 00750 he->tag = RPMTAG_BUILDHOST; 00751 he->t = RPM_STRING_TYPE; 00752 he->p.str = xstrdup(buildhost); 00753 he->c = 1; 00754 xx = headerPut(h, he, 0); 00755 he->p.ptr = _free(he->p.ptr); 00756 00757 { rpmuint32_t tid = rpmtsGetTid(ts); 00758 he->tag = RPMTAG_INSTALLTIME; 00759 he->t = RPM_UINT32_TYPE; 00760 he->p.ui32p = &tid; 00761 he->c = 1; 00762 xx = headerPut(h, he, 0); 00763 /* XXX W2DO: tag value inherited from parent? */ 00764 he->tag = RPMTAG_BUILDTIME; 00765 he->t = RPM_UINT32_TYPE; 00766 he->p.ui32p = &tid; 00767 he->c = 1; 00768 xx = headerPut(h, he, 0); 00769 } 00770 00771 #ifdef NOTYET 00772 /* XXX W2DO: tag value inherited from parent? */ 00773 he->tag = RPMTAG_SOURCERPM; 00774 he->t = RPM_STRING_TYPE; 00775 he->p.str = fn; 00776 he->c = 1; 00777 xx = headerPut(h, he, 0); 00778 #endif 00779 00780 /* Reallocate the pubkey header into an immutable region. */ 00781 he->tag = RPMTAG_HEADERIMMUTABLE; 00782 h = headerReload(h, he->tag); 00783 { size_t length = 0; 00784 he->t = RPM_BIN_TYPE; 00785 he->p.ptr = headerUnload(h, &length); 00786 he->c = length; 00787 } 00788 00789 /* Calculate the header-only SHA1 digest. */ 00790 { DIGEST_CTX ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE); 00791 unsigned char * hmagic = NULL; 00792 size_t nmagic = 0; 00793 const char * SHA1 = NULL; 00794 00795 (void) headerGetMagic(NULL, &hmagic, &nmagic); 00796 if (hmagic && nmagic > 0) 00797 (void) rpmDigestUpdate(ctx, hmagic, nmagic); 00798 (void) rpmDigestUpdate(ctx, he->p.ptr, he->c); 00799 (void) rpmDigestFinal(ctx, &SHA1, NULL, 1); 00800 he->p.ptr = _free(he->p.ptr); 00801 00802 if (SHA1 == NULL) 00803 goto exit; 00804 he->tag = RPMTAG_SHA1HEADER; 00805 he->t = RPM_STRING_TYPE; 00806 he->p.str = SHA1; 00807 he->c = 1; 00808 xx = headerPut(h, he, 0); 00809 SHA1 = _free(SHA1); 00810 } 00811 00812 he->tag = RPMTAG_PACKAGECOLOR; 00813 he->t = RPM_UINT32_TYPE; 00814 he->p.ui32p = &zero; 00815 he->c = 1; 00816 xx = headerPut(h, he, 0); 00817 00818 /* Add header to database. */ 00819 xx = rpmtxnBegin(rpmtsGetRdb(ts), NULL, NULL); 00820 xx = rpmdbAdd(rpmtsGetRdb(ts), rpmtsGetTid(ts), h, NULL); 00821 if (xx != 0) { 00822 xx = rpmtxnAbort(rpmtsGetRdb(ts)->db_txn); 00823 rpmtsGetRdb(ts)->db_txn = NULL; 00824 goto exit; 00825 } else 00826 xx = rpmtxnCommit(rpmtsGetRdb(ts)->db_txn); 00827 rpmtsGetRdb(ts)->db_txn = NULL; 00828 xx = rpmtxnCheckpoint(rpmtsGetRdb(ts)); 00829 rc = RPMRC_OK; 00830 00831 exit: 00832 /* Clean up. */ 00833 hkp->pkt = NULL; 00834 hkp->pktlen = 0; 00835 hkp->pkts = _free(hkp->pkts); 00836 hkp->npkts = 0; 00837 (void) rpmhkpFree(hkp); 00838 hkp = NULL; 00839 (void)headerFree(h); 00840 h = NULL; 00841 dig = pgpDigFree(dig); 00842 n = _free(n); 00843 u = _free(u); 00844 v = _free(v); 00845 r = _free(r); 00846 evr = _free(evr); 00847 enc = _free(enc); 00848 d = _free(d); 00849 00850 return rc; 00851 } 00852 00861 static int rpmcliImportPubkeys(const rpmts ts, 00862 /*@unused@*/ QVA_t qva, 00863 /*@null@*/ const char ** argv) 00864 /*@globals rpmGlobalMacroContext, h_errno, 00865 fileSystem, internalState @*/ 00866 /*@modifies ts, rpmGlobalMacroContext, 00867 fileSystem, internalState @*/ 00868 { 00869 const char * fn; 00870 rpmuint8_t * pkt = NULL; 00871 size_t pktlen = 0; 00872 char * t = NULL; 00873 int res = 0; 00874 rpmRC rpmrc; 00875 int rc; 00876 00877 if (argv == NULL) return res; 00878 00879 while ((fn = *argv++) != NULL) { 00880 00881 rpmtsClean(ts); 00882 pkt = _free(pkt); 00883 t = _free(t); 00884 00885 /* If arg looks like a keyid, then attempt keyserver retrieve. */ 00886 if (fn[0] == '0' && fn[1] == 'x') { 00887 const char * s; 00888 int i; 00889 for (i = 0, s = fn+2; *s && isxdigit(*s); s++, i++) 00890 {}; 00891 if (i == 8 || i == 16) { 00892 t = rpmExpand("%{_hkp_keyserver_query}", fn, NULL); 00893 if (t && *t != '%') 00894 fn = t; 00895 } 00896 } 00897 00898 /* Read pgp packet. */ 00899 if ((rc = pgpReadPkts(fn, &pkt, &pktlen)) <= 0) { 00900 rpmlog(RPMLOG_ERR, _("%s: import read failed(%d).\n"), fn, rc); 00901 res++; 00902 continue; 00903 } 00904 if (rc != PGPARMOR_PUBKEY) { 00905 rpmlog(RPMLOG_ERR, _("%s: not an armored public key.\n"), fn); 00906 res++; 00907 continue; 00908 } 00909 00910 /* Import pubkey packet(s). */ 00911 if ((rpmrc = rpmcliImportPubkey(ts, pkt, pktlen)) != RPMRC_OK) { 00912 rpmlog(RPMLOG_ERR, _("%s: import failed.\n"), fn); 00913 res++; 00914 continue; 00915 } 00916 00917 } 00918 00919 rpmtsClean(ts); 00920 pkt = _free(pkt); 00921 t = _free(t); 00922 return res; 00923 } 00924 00928 static rpmRC readFile(FD_t fd, const char * fn) 00929 /*@globals fileSystem, internalState @*/ 00930 /*@modifies fd, fileSystem, internalState @*/ 00931 { 00932 rpmxar xar = fdGetXAR(fd); 00933 pgpDig dig = fdGetDig(fd); 00934 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); 00935 unsigned char buf[4*BUFSIZ]; 00936 ssize_t count; 00937 unsigned ix; 00938 rpmRC rc; 00939 int xx; 00940 00941 dig->nbytes = 0; 00942 00943 /* Read the header from the package. */ 00944 { Header h = NULL; 00945 const char item[] = "Header"; 00946 const char * msg = NULL; 00947 rc = rpmpkgRead(item, fd, &h, &msg); 00948 if (rc != RPMRC_OK) { 00949 rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item, msg); 00950 msg = _free(msg); 00951 goto exit; 00952 } 00953 msg = _free(msg); 00954 00955 dig->nbytes += headerSizeof(h); 00956 00957 /* Fish out the autosign pubkey (if present). */ 00958 he->tag = RPMTAG_PUBKEYS; 00959 xx = headerGet(h, he, 0); 00960 if (xx && he->p.argv != NULL && he->c > 0) 00961 switch (he->t) { 00962 default: 00963 break; 00964 case RPM_STRING_ARRAY_TYPE: 00965 ix = he->c - 1; /* XXX FIXME: assumes last pubkey */ 00966 dig->pub = _free(dig->pub); 00967 dig->publen = 0; 00968 { rpmiob iob = rpmiobNew(0); 00969 iob = rpmiobAppend(iob, he->p.argv[ix], 0); 00970 xx = pgpArmorUnwrap(iob, (void *)&dig->pub, &dig->publen); 00971 iob = rpmiobFree(iob); 00972 } 00973 if (xx != PGPARMOR_PUBKEY) { 00974 dig->pub = _free(dig->pub); 00975 dig->publen = 0; 00976 } 00977 break; 00978 } 00979 he->p.ptr = _free(he->p.ptr); 00980 00981 if (headerIsEntry(h, RPMTAG_HEADERIMMUTABLE)) { 00982 unsigned char * hmagic = NULL; 00983 size_t nmagic = 0; 00984 00985 he->tag = RPMTAG_HEADERIMMUTABLE; 00986 xx = headerGet(h, he, 0); 00987 if (!xx || he->p.ptr == NULL) { 00988 (void)headerFree(h); 00989 h = NULL; 00990 rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, _("headerGet failed"), 00991 _("failed to retrieve original header\n")); 00992 rc = RPMRC_FAIL; 00993 goto exit; 00994 } 00995 (void) headerGetMagic(NULL, &hmagic, &nmagic); 00996 dig->hdrsha1ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE); 00997 if (hmagic && nmagic > 0) 00998 (void) rpmDigestUpdate(dig->hdrsha1ctx, hmagic, nmagic); 00999 (void) rpmDigestUpdate(dig->hdrsha1ctx, he->p.ptr, he->c); 01000 dig->hdrctx = rpmDigestInit(dig->signature.hash_algo, RPMDIGEST_NONE); 01001 if (hmagic && nmagic > 0) 01002 (void) rpmDigestUpdate(dig->hdrctx, hmagic, nmagic); 01003 (void) rpmDigestUpdate(dig->hdrctx, he->p.ptr, he->c); 01004 he->p.ptr = _free(he->p.ptr); 01005 } 01006 (void)headerFree(h); 01007 h = NULL; 01008 } 01009 01010 if (xar != NULL) { 01011 const char item[] = "Payload"; 01012 if ((xx = rpmxarNext(xar)) != 0 || (xx = rpmxarPull(xar, item)) != 0) { 01013 rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item, 01014 _("XAR file not found (or no XAR support)")); 01015 rc = RPMRC_NOTFOUND; 01016 goto exit; 01017 } 01018 } 01019 01020 /* Read the payload from the package. */ 01021 while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), fd)) > 0) 01022 dig->nbytes += count; 01023 if (count < 0 || Ferror(fd)) { 01024 rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, _("Fread failed"), Fstrerror(fd)); 01025 rc = RPMRC_FAIL; 01026 goto exit; 01027 } 01028 01029 /* XXX Steal the digest-in-progress from the file handle. */ 01030 fdStealDigest(fd, dig); 01031 01032 rc = RPMRC_OK; /* XXX unnecessary */ 01033 01034 exit: 01035 return rc; 01036 } 01037 01038 int rpmVerifySignatures(QVA_t qva, rpmts ts, void * _fd, const char * fn) 01039 { 01040 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); 01041 HE_t she = memset(alloca(sizeof(*she)), 0, sizeof(*she)); 01042 /*@-castexpose@*/ 01043 FD_t fd = (FD_t)_fd; 01044 /*@=castexpose@*/ 01045 char result[1024]; 01046 char buf[8192], * b; 01047 char missingKeys[7164], * m; 01048 char untrustedKeys[7164], * u; 01049 pgpDig dig; 01050 pgpDigParams sigp; 01051 Header sigh = NULL; 01052 HeaderIterator hi = NULL; 01053 int res = 0; 01054 int xx; 01055 rpmRC sigres; 01056 int failed; 01057 int nodigests = !(qva->qva_flags & VERIFY_DIGEST); 01058 int nosignatures = !(qva->qva_flags & VERIFY_SIGNATURE); 01059 pgpPkt pp = alloca(sizeof(*pp)); 01060 01061 { 01062 { const char item[] = "Lead"; 01063 const char * msg = NULL; 01064 rpmRC rc = rpmpkgRead(item, fd, NULL, &msg); 01065 switch (rc) { 01066 default: 01067 rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item, msg); 01068 msg = _free(msg); 01069 res++; 01070 goto exit; 01071 /*@notreachea@*/ break; 01072 case RPMRC_OK: 01073 break; 01074 } 01075 msg = _free(msg); 01076 } 01077 01078 { const char item[] = "Signature"; 01079 const char * msg = NULL; 01080 rpmRC rc = rpmpkgRead(item, fd, &sigh, &msg); 01081 switch (rc) { 01082 default: 01083 rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item, 01084 (msg && *msg ? msg : "")); 01085 msg = _free(msg); 01086 res++; 01087 goto exit; 01088 /*@notreached@*/ /*@switchbreak@*/ break; 01089 case RPMRC_OK: 01090 if (sigh == NULL) { 01091 rpmlog(RPMLOG_ERR, _("%s: No signature available\n"), fn); 01092 res++; 01093 goto exit; 01094 } 01095 /*@switchbreak@*/ break; 01096 } 01097 msg = _free(msg); 01098 } 01099 01100 /* Grab a hint of what needs doing to avoid duplication. */ 01101 she->tag = 0; 01102 if (she->tag == 0 && !nosignatures) { 01103 if (headerIsEntry(sigh, (rpmTag) RPMSIGTAG_DSA)) 01104 she->tag = (rpmTag) RPMSIGTAG_DSA; 01105 else if (headerIsEntry(sigh, (rpmTag) RPMSIGTAG_RSA)) 01106 she->tag = (rpmTag) RPMSIGTAG_RSA; 01107 } 01108 if (she->tag == 0 && !nodigests) { 01109 if (headerIsEntry(sigh, (rpmTag) RPMSIGTAG_MD5)) 01110 she->tag = (rpmTag) RPMSIGTAG_MD5; 01111 else if (headerIsEntry(sigh, (rpmTag) RPMSIGTAG_SHA1)) 01112 she->tag = (rpmTag) RPMSIGTAG_SHA1; /* XXX never happens */ 01113 } 01114 01115 dig = rpmtsDig(ts); 01116 /*@-mods@*/ /* LCL: avoid void * _fd annotation for now. */ 01117 (void) fdSetDig(fd, dig); 01118 /*@=mods@*/ 01119 sigp = pgpGetSignature(dig); 01120 01121 /* XXX RSA needs the hash_algo, so decode early. */ 01122 if ((rpmSigTag) she->tag == RPMSIGTAG_RSA) { 01123 he->tag = she->tag; 01124 xx = headerGet(sigh, he, 0); 01125 xx = pgpPktLen(he->p.ptr, he->c, pp); 01126 xx = rpmhkpLoadSignature(NULL, dig, pp); 01127 he->p.ptr = _free(he->p.ptr); 01128 } 01129 01130 /*@-mods@*/ /* LCL: avoid void * _fd annotation for now. */ 01131 if (headerIsEntry(sigh, (rpmTag)RPMSIGTAG_MD5)) 01132 fdInitDigest(fd, PGPHASHALGO_MD5, 0); 01133 /*@=mods@*/ 01134 01135 /* Read the file, generating digest(s) on the fly. */ 01136 /*@-mods@*/ /* LCL: avoid void * _fd annotation for now. */ 01137 if (dig == NULL || sigp == NULL 01138 || readFile(fd, fn) != RPMRC_OK) 01139 { 01140 res++; 01141 goto exit; 01142 } 01143 /*@=mods@*/ 01144 01145 failed = 0; 01146 b = buf; *b = '\0'; 01147 m = missingKeys; *m = '\0'; 01148 u = untrustedKeys; *u = '\0'; 01149 sprintf(b, "%s:%c", fn, (rpmIsVerbose() ? '\n' : ' ') ); 01150 b += strlen(b); 01151 01152 if (sigh != NULL) 01153 for (hi = headerInit(sigh); 01154 headerNext(hi, she, 0) != 0; 01155 she->p.ptr = _free(she->p.ptr)) 01156 { 01157 01158 assert(she->p.ptr != NULL); 01159 01160 /* Clean up parameters from previous she->tag. */ 01161 pgpDigClean(dig); 01162 01163 /*@-ownedtrans -noeffect@*/ 01164 xx = pgpSetSig(dig, she->tag, she->t, she->p.ptr, she->c); 01165 /*@=ownedtrans =noeffect@*/ 01166 01167 switch ((rpmSigTag)she->tag) { 01168 case RPMSIGTAG_RSA: 01169 case RPMSIGTAG_DSA: 01170 if (nosignatures) 01171 continue; 01172 01173 xx = pgpPktLen(she->p.ptr, she->c, pp); 01174 xx = rpmhkpLoadSignature(NULL, dig, pp); 01175 if (sigp->version != 3 && sigp->version != 4) { 01176 rpmlog(RPMLOG_ERR, 01177 _("skipping package %s with unverifiable V%u signature\n"), 01178 fn, sigp->version); 01179 res++; 01180 goto exit; 01181 } 01182 /*@switchbreak@*/ break; 01183 case RPMSIGTAG_SHA1: 01184 if (nodigests) 01185 continue; 01186 /* XXX Don't bother with header sha1 if header dsa. */ 01187 if (!nosignatures && (rpmSigTag)she->tag == RPMSIGTAG_DSA) 01188 continue; 01189 /*@switchbreak@*/ break; 01190 case RPMSIGTAG_MD5: 01191 if (nodigests) 01192 continue; 01193 /*@switchbreak@*/ break; 01194 default: 01195 continue; 01196 /*@notreached@*/ /*@switchbreak@*/ break; 01197 } 01198 01199 sigres = rpmVerifySignature(dig, result); 01200 01201 if (sigres) { 01202 failed = 1; 01203 if (rpmIsVerbose()) 01204 b = stpcpy( stpcpy( stpcpy(b, " "), result), "\n"); 01205 else 01206 switch ((rpmSigTag)she->tag) { 01207 case RPMSIGTAG_SIZE: 01208 b = stpcpy(b, "SIZE "); 01209 /*@switchbreak@*/ break; 01210 case RPMSIGTAG_SHA1: 01211 b = stpcpy(b, "SHA1 "); 01212 /*@switchbreak@*/ break; 01213 case RPMSIGTAG_MD5: 01214 b = stpcpy(b, "MD5 "); 01215 /*@switchbreak@*/ break; 01216 case RPMSIGTAG_RSA: 01217 b = stpcpy(b, "RSA "); 01218 /*@switchbreak@*/ break; 01219 case RPMSIGTAG_DSA: 01220 b = stpcpy(b, "(SHA1) DSA "); 01221 /*@switchbreak@*/ break; 01222 default: 01223 b = stpcpy(b, "?UnknownSignatureType? "); 01224 /*@switchbreak@*/ break; 01225 } 01226 } else { 01227 if (rpmIsVerbose()) 01228 b = stpcpy( stpcpy( stpcpy(b, " "), result), "\n"); 01229 else 01230 switch ((rpmSigTag)she->tag) { 01231 case RPMSIGTAG_SIZE: 01232 b = stpcpy(b, "size "); 01233 /*@switchbreak@*/ break; 01234 case RPMSIGTAG_SHA1: 01235 b = stpcpy(b, "sha1 "); 01236 /*@switchbreak@*/ break; 01237 case RPMSIGTAG_MD5: 01238 b = stpcpy(b, "md5 "); 01239 /*@switchbreak@*/ break; 01240 case RPMSIGTAG_RSA: 01241 b = stpcpy(b, "rsa "); 01242 /*@switchbreak@*/ break; 01243 case RPMSIGTAG_DSA: 01244 b = stpcpy(b, "(sha1) dsa "); 01245 /*@switchbreak@*/ break; 01246 default: 01247 b = stpcpy(b, "??? "); 01248 /*@switchbreak@*/ break; 01249 } 01250 } 01251 } 01252 hi = headerFini(hi); 01253 /* XXX clear the already free'd signature data. */ 01254 /*@-noeffect@*/ 01255 xx = pgpSetSig(dig, 0, 0, NULL, 0); 01256 /*@=noeffect@*/ 01257 01258 res += failed; 01259 01260 if (failed) { 01261 if (rpmIsVerbose()) { 01262 rpmlog(RPMLOG_NOTICE, "%s", buf); 01263 } else { 01264 rpmlog(RPMLOG_NOTICE, "%s%s%s%s%s%s%s%s\n", buf, 01265 _("NOT_OK"), 01266 (missingKeys[0] != '\0') ? _(" (MISSING KEYS:") : "", 01267 missingKeys, 01268 (missingKeys[0] != '\0') ? _(") ") : "", 01269 (untrustedKeys[0] != '\0') ? _(" (UNTRUSTED KEYS:") : "", 01270 untrustedKeys, 01271 (untrustedKeys[0] != '\0') ? _(")") : ""); 01272 01273 } 01274 } else { 01275 if (rpmIsVerbose()) { 01276 rpmlog(RPMLOG_NOTICE, "%s", buf); 01277 } else { 01278 rpmlog(RPMLOG_NOTICE, "%s%s%s%s%s%s%s%s\n", buf, 01279 _("OK"), 01280 (missingKeys[0] != '\0') ? _(" (MISSING KEYS:") : "", 01281 missingKeys, 01282 (missingKeys[0] != '\0') ? _(") ") : "", 01283 (untrustedKeys[0] != '\0') ? _(" (UNTRUSTED KEYS:") : "", 01284 untrustedKeys, 01285 (untrustedKeys[0] != '\0') ? _(")") : ""); 01286 } 01287 } 01288 01289 } 01290 01291 exit: 01292 rpmtsCleanDig(ts); 01293 (void)headerFree(sigh); 01294 sigh = NULL; 01295 return res; 01296 } 01297 01298 int rpmcliSign(rpmts ts, QVA_t qva, const char ** argv) 01299 /*@globals rpmioFtsOpts @*/ 01300 /*@modifies rpmioFtsOpts @*/ 01301 { 01302 rpmRC rpmrc; 01303 int res = 0; 01304 01305 if (argv == NULL) return res; 01306 01307 switch (qva->qva_mode) { 01308 case RPMSIGN_CHK_SIGNATURE: 01309 break; 01310 case RPMSIGN_IMPORT_PUBKEY: 01311 return rpmcliImportPubkeys(ts, qva, argv); 01312 /*@notreached@*/ break; 01313 case RPMSIGN_NEW_SIGNATURE: 01314 case RPMSIGN_ADD_SIGNATURE: 01315 case RPMSIGN_DEL_SIGNATURE: 01316 return rpmReSign(ts, qva, argv); 01317 /*@notreached@*/ break; 01318 case RPMSIGN_NONE: 01319 default: 01320 return -1; 01321 /*@notreached@*/ break; 01322 } 01323 01324 { /* start-of-arg-iteration */ 01325 01326 int tag = (qva->qva_source == RPMQV_FTSWALK) 01327 ? RPMDBI_FTSWALK : RPMDBI_ARGLIST; 01328 rpmgi gi = rpmgiNew(ts, tag, NULL, 0); 01329 rpmgiFlags _giFlags = RPMGI_NONE; 01330 rpmRC rc; 01331 01332 if (rpmioFtsOpts == 0) 01333 rpmioFtsOpts = (FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOSTAT); 01334 rc = rpmgiSetArgs(gi, argv, rpmioFtsOpts, (_giFlags|RPMGI_NOHEADER)); 01335 while ((rpmrc = rpmgiNext(gi)) == RPMRC_OK) { 01336 const char * fn = rpmgiHdrPath(gi); 01337 FD_t fd; 01338 int xx; 01339 01340 fd = Fopen(fn, "r.fdio"); 01341 if (fd == NULL || Ferror(fd)) { 01342 rpmlog(RPMLOG_ERR, _("%s: open failed: %s\n"), 01343 fn, Fstrerror(fd)); 01344 res++; 01345 } else if (rpmVerifySignatures(qva, ts, fd, fn)) { 01346 res++; 01347 } 01348 01349 if (fd != NULL) { 01350 xx = Fclose(fd); 01351 } 01352 } 01353 01354 /* XXX disambiguate end-of-iteration from item failures. */ 01355 if (res == 0 && rpmrc == RPMRC_NOTFOUND) { 01356 rpmrc = rpmgiRc(gi); 01357 if (rpmrc != RPMRC_OK) 01358 res++; 01359 } 01360 01361 gi = rpmgiFree(gi); 01362 01363 } /* end-of-arg-iteration */ 01364 01365 return res; 01366 }
1.7.5.1