rpm 5.3.7
|
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 const char * msg = NULL; 00205 int res = EXIT_FAILURE; 00206 int deleting = (qva->qva_mode == RPMSIGN_DEL_SIGNATURE); 00207 rpmRC rc; 00208 int xx; 00209 int i; 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 rc = rpmgiSetArgs(gi, argv, rpmioFtsOpts, (_giFlags|RPMGI_NOHEADER)); 00225 00226 while (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 msg = NULL; 00239 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 msg = NULL; 00250 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 (void) close(mkstemp(tmprpm)); 00422 #else 00423 (void) mktemp(tmprpm); 00424 #endif 00425 tfn = tmprpm; 00426 00427 if (manageFile(&ofd, &tfn, O_WRONLY|O_CREAT|O_TRUNC, 0)) 00428 goto exit; 00429 00430 { const char item[] = "Lead"; 00431 rc = rpmpkgWrite(item, ofd, lead, NULL); 00432 if (rc != RPMRC_OK) { 00433 rpmlog(RPMLOG_ERR, "%s: %s: %s\n", tfn, item, Fstrerror(ofd)); 00434 goto exit; 00435 } 00436 } 00437 00438 { const char item[] = "Signature"; 00439 rc = rpmpkgWrite(item, ofd, sigh, NULL); 00440 if (rc != RPMRC_OK) { 00441 rpmlog(RPMLOG_ERR, "%s: %s: %s\n", tfn, item, Fstrerror(ofd)); 00442 goto exit; 00443 } 00444 } 00445 (void)headerFree(sigh); 00446 sigh = NULL; 00447 00448 /* Append the header and archive from the temp file */ 00449 /* ASSERT: fd == NULL && ofd != NULL */ 00450 if (copyFile(&fd, &sigtarget, &ofd, &tfn)) 00451 goto exit; 00452 /* Both fd and ofd are now closed. */ 00453 /* ASSERT: fd == NULL && ofd == NULL */ 00454 00455 /* Move final target into place. */ 00456 xx = Unlink(fn); 00457 xx = Rename(tfn, fn); 00458 tmprpm[0] = '\0'; 00459 00460 /* Clean up intermediate target */ 00461 xx = Unlink(sigtarget); 00462 sigtarget = _free(sigtarget); 00463 } 00464 00465 } /* end-of-arg-iteration */ 00466 00467 res = 0; 00468 00469 exit: 00470 if (fd) (void) manageFile(&fd, NULL, 0, res); 00471 if (ofd) (void) manageFile(&ofd, NULL, 0, res); 00472 00473 lead = _free(lead); 00474 (void)headerFree(sigh); 00475 sigh = NULL; 00476 00477 gi = rpmgiFree(gi); 00478 00479 if (sigtarget) { 00480 xx = Unlink(sigtarget); 00481 sigtarget = _free(sigtarget); 00482 } 00483 if (tmprpm[0] != '\0') { 00484 xx = Unlink(tmprpm); 00485 tmprpm[0] = '\0'; 00486 } 00487 00488 return res; 00489 } 00490 00491 rpmRC rpmcliImportPubkey(const rpmts ts, const unsigned char * pkt, ssize_t pktlen) 00492 { 00493 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); 00494 static unsigned char zeros[] = 00495 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 00496 const char * afmt = "%{pubkeys:armor}"; 00497 const char * group = "Public Keys"; 00498 const char * license = "pubkey"; 00499 const char * buildhost = "localhost"; 00500 rpmuint32_t pflags = (RPMSENSE_KEYRING|RPMSENSE_EQUAL); 00501 rpmuint32_t zero = 0; 00502 pgpDig dig = NULL; 00503 pgpDigParams pubp = NULL; 00504 const char * d = NULL; 00505 const char * enc = NULL; 00506 const char * n = NULL; 00507 const char * u = NULL; 00508 const char * v = NULL; 00509 const char * r = NULL; 00510 const char * evr = NULL; 00511 Header h = NULL; 00512 rpmRC rc = RPMRC_FAIL; /* assume failure */ 00513 char * t; 00514 int xx; 00515 rpmhkp hkp = NULL; 00516 pgpPkt pp = alloca(sizeof(*pp)); 00517 int validate = 1; 00518 00519 if (pkt == NULL || pktlen <= 0) 00520 return RPMRC_FAIL; 00521 if (rpmtsOpenDB(ts, (O_RDWR|O_CREAT))) 00522 return RPMRC_FAIL; 00523 00524 /*@-moduncon@*/ 00525 if ((enc = b64encode(pkt, pktlen)) == NULL) 00526 goto exit; 00527 /*@=moduncon@*/ 00528 00529 dig = pgpDigNew(RPMVSF_DEFAULT, 0); 00530 pubp = pgpGetPubkey(dig); 00531 00532 //* Validate the pubkey. */ 00533 if (ts->hkp == NULL) 00534 ts->hkp = rpmhkpNew(NULL, 0); 00535 hkp = rpmhkpLink(ts->hkp); 00536 hkp->pkt = (rpmuint8_t *)pkt; 00537 hkp->pktlen = pktlen; 00538 00539 xx = pgpGrabPkts(hkp->pkt, hkp->pktlen, &hkp->pkts, &hkp->npkts); 00540 if (!xx) 00541 (void) pgpPubkeyFingerprint(hkp->pkt, hkp->pktlen, hkp->keyid); 00542 memcpy(pubp->signid, hkp->keyid, sizeof(pubp->signid)); /* XXX useless */ 00543 00544 xx = pgpPktLen(hkp->pkt, hkp->pktlen, pp); 00545 00546 xx = rpmhkpLoadKey(hkp, dig, 0, 0); 00547 00548 /* Validate pubkey self-signatures. */ 00549 if (validate) { 00550 rpmRC yy = rpmhkpValidate(hkp, NULL); 00551 switch (yy) { 00552 case RPMRC_OK: 00553 break; 00554 case RPMRC_NOTFOUND: 00555 case RPMRC_FAIL: /* XXX remap to NOTFOUND? */ 00556 case RPMRC_NOTTRUSTED: 00557 case RPMRC_NOKEY: 00558 default: 00559 #ifdef NOTYET /* XXX make check-pubkey fails?!? . */ 00560 rc = yy; 00561 goto exit; 00562 #endif 00563 /*@notreached@*/ break; 00564 } 00565 } 00566 00567 /* XXX hack up a user id (if not already present) */ 00568 if (pubp->userid == NULL) { 00569 if (hkp->uidx >= 0 && hkp->uidx < hkp->npkts) { 00570 size_t nb = pgpPktLen(hkp->pkts[hkp->uidx], hkp->pktlen, pp); 00571 char * t; 00572 nb = pp->hlen; 00573 t = memcpy(xmalloc(nb + 1), pp->u.u->userid, nb); 00574 t[nb] = '\0'; 00575 pubp->userid = t; 00576 } else 00577 pubp->userid = xstrdup(pgpHexStr(pubp->signid+4, 4)); 00578 } 00579 00580 #ifdef DYING 00581 _rpmhkpDumpDig(__FUNCTION__, dig); 00582 #endif 00583 00584 /* Build header elements. */ 00585 if (!memcmp(pubp->signid, zeros, sizeof(pubp->signid)) 00586 || !memcmp(pubp->time, zeros, sizeof(pubp->time)) 00587 || pubp->userid == NULL) 00588 goto exit; 00589 00590 v = t = xmalloc(16+1); 00591 t = stpcpy(t, pgpHexStr(pubp->signid, sizeof(pubp->signid))); 00592 00593 r = t = xmalloc(8+1); 00594 t = stpcpy(t, pgpHexStr(pubp->time, sizeof(pubp->time))); 00595 00596 n = t = xmalloc(sizeof("gpg()")+8); 00597 t = stpcpy( stpcpy( stpcpy(t, "gpg("), v+8), ")"); 00598 00599 { const char * userid = 00600 (pubp->userid ? pubp->userid : pgpHexStr(pubp->signid+4, 4)); 00601 u = t = xmalloc(sizeof("gpg()")+strlen(userid)); 00602 t = stpcpy( stpcpy( stpcpy(t, "gpg("), userid), ")"); 00603 } 00604 00605 evr = t = xmalloc(sizeof("4X:-")+strlen(v)+strlen(r)); 00606 t = stpcpy(t, (pubp->version == 4 ? "4:" : "3:")); 00607 t = stpcpy( stpcpy( stpcpy(t, v), "-"), r); 00608 00609 /* Check for pre-existing header. */ 00610 00611 /* Build pubkey header. */ 00612 h = headerNew(); 00613 00614 he->append = 1; 00615 00616 he->tag = RPMTAG_PUBKEYS; 00617 he->t = RPM_STRING_ARRAY_TYPE; 00618 he->p.argv = &enc; 00619 he->c = 1; 00620 xx = headerPut(h, he, 0); 00621 00622 he->append = 0; 00623 00624 d = headerSprintf(h, afmt, NULL, rpmHeaderFormats, NULL); 00625 if (d == NULL) 00626 goto exit; 00627 00628 he->t = RPM_STRING_TYPE; 00629 he->c = 1; 00630 he->tag = RPMTAG_NAME; 00631 he->p.str = xstrdup("gpg-pubkey"); 00632 xx = headerPut(h, he, 0); 00633 he->p.ptr = _free(he->p.ptr); 00634 he->tag = RPMTAG_VERSION; 00635 he->p.str = v+8; 00636 xx = headerPut(h, he, 0); 00637 he->tag = RPMTAG_RELEASE; 00638 he->p.str = xstrdup(r); 00639 xx = headerPut(h, he, 0); 00640 he->p.ptr = _free(he->p.ptr); 00641 00642 /* Add Summary/Description/Group. */ 00643 he->tag = RPMTAG_DESCRIPTION; 00644 he->p.str = xstrdup(d); 00645 #if defined(SUPPORT_IMPLICIT_TAG_DATA_TYPES) 00646 xx = headerAddI18NString(h, he->tag, he->p.ptr, "C"); 00647 #else 00648 xx = headerPut(h, he, 0); 00649 #endif 00650 he->p.ptr = _free(he->p.ptr); 00651 00652 he->tag = RPMTAG_GROUP; 00653 he->p.str = xstrdup(group); 00654 #if defined(SUPPORT_IMPLICIT_TAG_DATA_TYPES) 00655 xx = headerAddI18NString(h, he->tag, he->p.ptr, "C"); 00656 #else 00657 xx = headerPut(h, he, 0); 00658 #endif 00659 he->p.ptr = _free(he->p.ptr); 00660 00661 he->tag = RPMTAG_SUMMARY; 00662 he->p.str = xstrdup(u); 00663 #if defined(SUPPORT_IMPLICIT_TAG_DATA_TYPES) 00664 xx = headerAddI18NString(h, he->tag, he->p.ptr, "C"); 00665 #else 00666 xx = headerPut(h, he, 0); 00667 #endif 00668 he->p.ptr = _free(he->p.ptr); 00669 00670 #ifdef NOTYET /* XXX can't erase pubkeys with "pubkey" arch. */ 00671 /* Add a "pubkey" arch/os to avoid missing value NULL ptrs. */ 00672 he->tag = RPMTAG_ARCH; 00673 he->p.str = "pubkey"; 00674 xx = headerPut(h, he, 0); 00675 he->tag = RPMTAG_OS; 00676 he->p.str = "pubkey"; 00677 xx = headerPut(h, he, 0); 00678 #endif 00679 00680 he->tag = RPMTAG_LICENSE; 00681 he->p.str = xstrdup(license); 00682 xx = headerPut(h, he, 0); 00683 he->p.ptr = _free(he->p.ptr); 00684 00685 he->tag = RPMTAG_SIZE; 00686 he->t = RPM_UINT32_TYPE; 00687 he->p.ui32p = &zero; 00688 he->c = 1; 00689 xx = headerPut(h, he, 0); 00690 00691 he->append = 1; 00692 00693 /* Provides: gpg(IDENTITY) = PUBKEYVERSIONTYPE:PUBKEYID-CREATION */ 00694 he->tag = RPMTAG_PROVIDENAME; 00695 he->t = RPM_STRING_ARRAY_TYPE; 00696 he->p.argv = &u; 00697 he->c = 1; 00698 xx = headerPut(h, he, 0); 00699 he->tag = RPMTAG_PROVIDEVERSION; 00700 he->t = RPM_STRING_ARRAY_TYPE; 00701 he->p.argv = &evr; 00702 he->c = 1; 00703 xx = headerPut(h, he, 0); 00704 he->tag = RPMTAG_PROVIDEFLAGS; 00705 he->t = RPM_UINT32_TYPE; 00706 he->p.ui32p = &pflags; 00707 he->c = 1; 00708 xx = headerPut(h, he, 0); 00709 00710 /* Provides: gpg(PUBKEYID) = PUBKEYVERSION:PUBKEYID-CREATION */ 00711 he->tag = RPMTAG_PROVIDENAME; 00712 he->t = RPM_STRING_ARRAY_TYPE; 00713 he->p.argv = &n; 00714 he->c = 1; 00715 xx = headerPut(h, he, 0); 00716 he->tag = RPMTAG_PROVIDEVERSION; 00717 he->t = RPM_STRING_ARRAY_TYPE; 00718 he->p.argv = &evr; 00719 he->c = 1; 00720 xx = headerPut(h, he, 0); 00721 he->tag = RPMTAG_PROVIDEFLAGS; 00722 he->t = RPM_UINT32_TYPE; 00723 he->p.ui32p = &pflags; 00724 he->c = 1; 00725 xx = headerPut(h, he, 0); 00726 00727 he->append = 0; 00728 00729 he->tag = RPMTAG_RPMVERSION; 00730 he->t = RPM_STRING_TYPE; 00731 he->p.str = xstrdup(RPMVERSION); 00732 he->c = 1; 00733 xx = headerPut(h, he, 0); 00734 he->p.ptr = _free(he->p.ptr); 00735 00736 /* XXX W2DO: tag value inherited from parent? */ 00737 he->tag = RPMTAG_BUILDHOST; 00738 he->t = RPM_STRING_TYPE; 00739 he->p.str = xstrdup(buildhost); 00740 he->c = 1; 00741 xx = headerPut(h, he, 0); 00742 he->p.ptr = _free(he->p.ptr); 00743 00744 { rpmuint32_t tid = rpmtsGetTid(ts); 00745 he->tag = RPMTAG_INSTALLTIME; 00746 he->t = RPM_UINT32_TYPE; 00747 he->p.ui32p = &tid; 00748 he->c = 1; 00749 xx = headerPut(h, he, 0); 00750 /* XXX W2DO: tag value inherited from parent? */ 00751 he->tag = RPMTAG_BUILDTIME; 00752 he->t = RPM_UINT32_TYPE; 00753 he->p.ui32p = &tid; 00754 he->c = 1; 00755 xx = headerPut(h, he, 0); 00756 } 00757 00758 #ifdef NOTYET 00759 /* XXX W2DO: tag value inherited from parent? */ 00760 he->tag = RPMTAG_SOURCERPM; 00761 he->t = RPM_STRING_TYPE; 00762 he->p.str = fn; 00763 he->c = 1; 00764 xx = headerPut(h, he, 0); 00765 #endif 00766 00767 /* Reallocate the pubkey header into an immutable region. */ 00768 he->tag = RPMTAG_HEADERIMMUTABLE; 00769 h = headerReload(h, he->tag); 00770 { size_t length = 0; 00771 he->t = RPM_BIN_TYPE; 00772 he->p.ptr = headerUnload(h, &length); 00773 he->c = length; 00774 } 00775 00776 /* Calculate the header-only SHA1 digest. */ 00777 { DIGEST_CTX ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE); 00778 unsigned char * hmagic = NULL; 00779 size_t nmagic = 0; 00780 const char * SHA1 = NULL; 00781 00782 (void) headerGetMagic(NULL, &hmagic, &nmagic); 00783 if (hmagic && nmagic > 0) 00784 (void) rpmDigestUpdate(ctx, hmagic, nmagic); 00785 (void) rpmDigestUpdate(ctx, he->p.ptr, he->c); 00786 (void) rpmDigestFinal(ctx, &SHA1, NULL, 1); 00787 he->p.ptr = _free(he->p.ptr); 00788 00789 if (SHA1 == NULL) 00790 goto exit; 00791 he->tag = RPMTAG_SHA1HEADER; 00792 he->t = RPM_STRING_TYPE; 00793 he->p.str = SHA1; 00794 he->c = 1; 00795 xx = headerPut(h, he, 0); 00796 SHA1 = _free(SHA1); 00797 } 00798 00799 he->tag = RPMTAG_PACKAGECOLOR; 00800 he->t = RPM_UINT32_TYPE; 00801 he->p.ui32p = &zero; 00802 he->c = 1; 00803 xx = headerPut(h, he, 0); 00804 00805 /* Add header to database. */ 00806 xx = rpmtxnBegin(rpmtsGetRdb(ts), NULL, NULL); 00807 xx = rpmdbAdd(rpmtsGetRdb(ts), rpmtsGetTid(ts), h, NULL); 00808 if (xx != 0) { 00809 xx = rpmtxnAbort(rpmtsGetRdb(ts)->db_txn); 00810 rpmtsGetRdb(ts)->db_txn = NULL; 00811 goto exit; 00812 } else 00813 xx = rpmtxnCommit(rpmtsGetRdb(ts)->db_txn); 00814 rpmtsGetRdb(ts)->db_txn = NULL; 00815 xx = rpmtxnCheckpoint(rpmtsGetRdb(ts)); 00816 rc = RPMRC_OK; 00817 00818 exit: 00819 /* Clean up. */ 00820 hkp->pkt = NULL; 00821 hkp->pktlen = 0; 00822 hkp->pkts = _free(hkp->pkts); 00823 hkp->npkts = 0; 00824 (void) rpmhkpFree(hkp); 00825 hkp = NULL; 00826 (void)headerFree(h); 00827 h = NULL; 00828 dig = pgpDigFree(dig); 00829 n = _free(n); 00830 u = _free(u); 00831 v = _free(v); 00832 r = _free(r); 00833 evr = _free(evr); 00834 enc = _free(enc); 00835 d = _free(d); 00836 00837 return rc; 00838 } 00839 00848 static int rpmcliImportPubkeys(const rpmts ts, 00849 /*@unused@*/ QVA_t qva, 00850 /*@null@*/ const char ** argv) 00851 /*@globals rpmGlobalMacroContext, h_errno, 00852 fileSystem, internalState @*/ 00853 /*@modifies ts, rpmGlobalMacroContext, 00854 fileSystem, internalState @*/ 00855 { 00856 const char * fn; 00857 rpmuint8_t * pkt = NULL; 00858 size_t pktlen = 0; 00859 char * t = NULL; 00860 int res = 0; 00861 rpmRC rpmrc; 00862 int rc; 00863 00864 if (argv == NULL) return res; 00865 00866 while ((fn = *argv++) != NULL) { 00867 00868 rpmtsClean(ts); 00869 pkt = _free(pkt); 00870 t = _free(t); 00871 00872 /* If arg looks like a keyid, then attempt keyserver retrieve. */ 00873 if (fn[0] == '0' && fn[1] == 'x') { 00874 const char * s; 00875 int i; 00876 for (i = 0, s = fn+2; *s && isxdigit(*s); s++, i++) 00877 {}; 00878 if (i == 8 || i == 16) { 00879 t = rpmExpand("%{_hkp_keyserver_query}", fn, NULL); 00880 if (t && *t != '%') 00881 fn = t; 00882 } 00883 } 00884 00885 /* Read pgp packet. */ 00886 if ((rc = pgpReadPkts(fn, &pkt, &pktlen)) <= 0) { 00887 rpmlog(RPMLOG_ERR, _("%s: import read failed(%d).\n"), fn, rc); 00888 res++; 00889 continue; 00890 } 00891 if (rc != PGPARMOR_PUBKEY) { 00892 rpmlog(RPMLOG_ERR, _("%s: not an armored public key.\n"), fn); 00893 res++; 00894 continue; 00895 } 00896 00897 /* Import pubkey packet(s). */ 00898 if ((rpmrc = rpmcliImportPubkey(ts, pkt, pktlen)) != RPMRC_OK) { 00899 rpmlog(RPMLOG_ERR, _("%s: import failed.\n"), fn); 00900 res++; 00901 continue; 00902 } 00903 00904 } 00905 00906 rpmtsClean(ts); 00907 pkt = _free(pkt); 00908 t = _free(t); 00909 return res; 00910 } 00911 00915 static rpmRC readFile(FD_t fd, const char * fn) 00916 /*@globals fileSystem, internalState @*/ 00917 /*@modifies fd, fileSystem, internalState @*/ 00918 { 00919 rpmxar xar = fdGetXAR(fd); 00920 pgpDig dig = fdGetDig(fd); 00921 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); 00922 unsigned char buf[4*BUFSIZ]; 00923 ssize_t count; 00924 unsigned ix; 00925 rpmRC rc; 00926 int xx; 00927 00928 dig->nbytes = 0; 00929 00930 /* Read the header from the package. */ 00931 { Header h = NULL; 00932 const char item[] = "Header"; 00933 const char * msg = NULL; 00934 rc = rpmpkgRead(item, fd, &h, &msg); 00935 if (rc != RPMRC_OK) { 00936 rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item, msg); 00937 msg = _free(msg); 00938 goto exit; 00939 } 00940 msg = _free(msg); 00941 00942 dig->nbytes += headerSizeof(h); 00943 00944 /* Fish out the autosign pubkey (if present). */ 00945 he->tag = RPMTAG_PUBKEYS; 00946 xx = headerGet(h, he, 0); 00947 if (xx && he->p.argv != NULL && he->c > 0) 00948 switch (he->t) { 00949 default: 00950 break; 00951 case RPM_STRING_ARRAY_TYPE: 00952 ix = he->c - 1; /* XXX FIXME: assumes last pubkey */ 00953 dig->pub = _free(dig->pub); 00954 dig->publen = 0; 00955 { rpmiob iob = rpmiobNew(0); 00956 iob = rpmiobAppend(iob, he->p.argv[ix], 0); 00957 xx = pgpArmorUnwrap(iob, (void *)&dig->pub, &dig->publen); 00958 iob = rpmiobFree(iob); 00959 } 00960 if (xx != PGPARMOR_PUBKEY) { 00961 dig->pub = _free(dig->pub); 00962 dig->publen = 0; 00963 } 00964 break; 00965 } 00966 he->p.ptr = _free(he->p.ptr); 00967 00968 if (headerIsEntry(h, RPMTAG_HEADERIMMUTABLE)) { 00969 unsigned char * hmagic = NULL; 00970 size_t nmagic = 0; 00971 00972 he->tag = RPMTAG_HEADERIMMUTABLE; 00973 xx = headerGet(h, he, 0); 00974 if (!xx || he->p.ptr == NULL) { 00975 (void)headerFree(h); 00976 h = NULL; 00977 rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, _("headerGet failed"), 00978 _("failed to retrieve original header\n")); 00979 rc = RPMRC_FAIL; 00980 goto exit; 00981 } 00982 (void) headerGetMagic(NULL, &hmagic, &nmagic); 00983 dig->hdrsha1ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE); 00984 if (hmagic && nmagic > 0) 00985 (void) rpmDigestUpdate(dig->hdrsha1ctx, hmagic, nmagic); 00986 (void) rpmDigestUpdate(dig->hdrsha1ctx, he->p.ptr, he->c); 00987 dig->hdrctx = rpmDigestInit(dig->signature.hash_algo, RPMDIGEST_NONE); 00988 if (hmagic && nmagic > 0) 00989 (void) rpmDigestUpdate(dig->hdrctx, hmagic, nmagic); 00990 (void) rpmDigestUpdate(dig->hdrctx, he->p.ptr, he->c); 00991 he->p.ptr = _free(he->p.ptr); 00992 } 00993 (void)headerFree(h); 00994 h = NULL; 00995 } 00996 00997 if (xar != NULL) { 00998 const char item[] = "Payload"; 00999 if ((xx = rpmxarNext(xar)) != 0 || (xx = rpmxarPull(xar, item)) != 0) { 01000 rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item, 01001 _("XAR file not found (or no XAR support)")); 01002 rc = RPMRC_NOTFOUND; 01003 goto exit; 01004 } 01005 } 01006 01007 /* Read the payload from the package. */ 01008 while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), fd)) > 0) 01009 dig->nbytes += count; 01010 if (count < 0 || Ferror(fd)) { 01011 rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, _("Fread failed"), Fstrerror(fd)); 01012 rc = RPMRC_FAIL; 01013 goto exit; 01014 } 01015 01016 /* XXX Steal the digest-in-progress from the file handle. */ 01017 fdStealDigest(fd, dig); 01018 01019 rc = RPMRC_OK; /* XXX unnecessary */ 01020 01021 exit: 01022 return rc; 01023 } 01024 01025 int rpmVerifySignatures(QVA_t qva, rpmts ts, void * _fd, const char * fn) 01026 { 01027 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); 01028 HE_t she = memset(alloca(sizeof(*she)), 0, sizeof(*she)); 01029 /*@-castexpose@*/ 01030 FD_t fd = (FD_t)_fd; 01031 /*@=castexpose@*/ 01032 char result[1024]; 01033 char buf[8192], * b; 01034 char missingKeys[7164], * m; 01035 char untrustedKeys[7164], * u; 01036 pgpDig dig; 01037 pgpDigParams sigp; 01038 Header sigh = NULL; 01039 HeaderIterator hi = NULL; 01040 const char * msg = NULL; 01041 int res = 0; 01042 int xx; 01043 rpmRC rc, sigres; 01044 int failed; 01045 int nodigests = !(qva->qva_flags & VERIFY_DIGEST); 01046 int nosignatures = !(qva->qva_flags & VERIFY_SIGNATURE); 01047 pgpPkt pp = alloca(sizeof(*pp)); 01048 01049 { 01050 { const char item[] = "Lead"; 01051 msg = NULL; 01052 /*@-mods@*/ /* LCL: avoid void * _fd annotation for now. */ 01053 rc = rpmpkgRead(item, fd, NULL, &msg); 01054 /*@=mods@*/ 01055 if (rc != RPMRC_OK) { 01056 rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item, msg); 01057 msg = _free(msg); 01058 res++; 01059 goto exit; 01060 } 01061 msg = _free(msg); 01062 } 01063 01064 { const char item[] = "Signature"; 01065 msg = NULL; 01066 /*@-mods@*/ /* LCL: avoid void * _fd annotation for now. */ 01067 rc = rpmpkgRead(item, fd, &sigh, &msg); 01068 /*@=mods@*/ 01069 switch (rc) { 01070 default: 01071 rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item, 01072 (msg && *msg ? msg : "")); 01073 msg = _free(msg); 01074 res++; 01075 goto exit; 01076 /*@notreached@*/ /*@switchbreak@*/ break; 01077 case RPMRC_OK: 01078 if (sigh == NULL) { 01079 rpmlog(RPMLOG_ERR, _("%s: No signature available\n"), fn); 01080 res++; 01081 goto exit; 01082 } 01083 /*@switchbreak@*/ break; 01084 } 01085 msg = _free(msg); 01086 } 01087 01088 /* Grab a hint of what needs doing to avoid duplication. */ 01089 she->tag = 0; 01090 if (she->tag == 0 && !nosignatures) { 01091 if (headerIsEntry(sigh, (rpmTag) RPMSIGTAG_DSA)) 01092 she->tag = (rpmTag) RPMSIGTAG_DSA; 01093 else if (headerIsEntry(sigh, (rpmTag) RPMSIGTAG_RSA)) 01094 she->tag = (rpmTag) RPMSIGTAG_RSA; 01095 } 01096 if (she->tag == 0 && !nodigests) { 01097 if (headerIsEntry(sigh, (rpmTag) RPMSIGTAG_MD5)) 01098 she->tag = (rpmTag) RPMSIGTAG_MD5; 01099 else if (headerIsEntry(sigh, (rpmTag) RPMSIGTAG_SHA1)) 01100 she->tag = (rpmTag) RPMSIGTAG_SHA1; /* XXX never happens */ 01101 } 01102 01103 dig = rpmtsDig(ts); 01104 /*@-mods@*/ /* LCL: avoid void * _fd annotation for now. */ 01105 (void) fdSetDig(fd, dig); 01106 /*@=mods@*/ 01107 sigp = pgpGetSignature(dig); 01108 01109 /* XXX RSA needs the hash_algo, so decode early. */ 01110 if ((rpmSigTag) she->tag == RPMSIGTAG_RSA) { 01111 he->tag = she->tag; 01112 xx = headerGet(sigh, he, 0); 01113 xx = pgpPktLen(he->p.ptr, he->c, pp); 01114 xx = rpmhkpLoadSignature(NULL, dig, pp); 01115 he->p.ptr = _free(he->p.ptr); 01116 } 01117 01118 /*@-mods@*/ /* LCL: avoid void * _fd annotation for now. */ 01119 if (headerIsEntry(sigh, (rpmTag)RPMSIGTAG_MD5)) 01120 fdInitDigest(fd, PGPHASHALGO_MD5, 0); 01121 /*@=mods@*/ 01122 01123 /* Read the file, generating digest(s) on the fly. */ 01124 /*@-mods@*/ /* LCL: avoid void * _fd annotation for now. */ 01125 if (dig == NULL || sigp == NULL 01126 || readFile(fd, fn) != RPMRC_OK) 01127 { 01128 res++; 01129 goto exit; 01130 } 01131 /*@=mods@*/ 01132 01133 failed = 0; 01134 b = buf; *b = '\0'; 01135 m = missingKeys; *m = '\0'; 01136 u = untrustedKeys; *u = '\0'; 01137 sprintf(b, "%s:%c", fn, (rpmIsVerbose() ? '\n' : ' ') ); 01138 b += strlen(b); 01139 01140 if (sigh != NULL) 01141 for (hi = headerInit(sigh); 01142 headerNext(hi, she, 0) != 0; 01143 she->p.ptr = _free(she->p.ptr)) 01144 { 01145 01146 assert(she->p.ptr != NULL); 01147 01148 /* Clean up parameters from previous she->tag. */ 01149 pgpDigClean(dig); 01150 01151 /*@-ownedtrans -noeffect@*/ 01152 xx = pgpSetSig(dig, she->tag, she->t, she->p.ptr, she->c); 01153 /*@=ownedtrans =noeffect@*/ 01154 01155 switch ((rpmSigTag)she->tag) { 01156 case RPMSIGTAG_RSA: 01157 case RPMSIGTAG_DSA: 01158 if (nosignatures) 01159 continue; 01160 01161 xx = pgpPktLen(she->p.ptr, she->c, pp); 01162 xx = rpmhkpLoadSignature(NULL, dig, pp); 01163 if (sigp->version != 3 && sigp->version != 4) { 01164 rpmlog(RPMLOG_ERR, 01165 _("skipping package %s with unverifiable V%u signature\n"), 01166 fn, sigp->version); 01167 res++; 01168 goto exit; 01169 } 01170 /*@switchbreak@*/ break; 01171 case RPMSIGTAG_SHA1: 01172 if (nodigests) 01173 continue; 01174 /* XXX Don't bother with header sha1 if header dsa. */ 01175 if (!nosignatures && (rpmSigTag)she->tag == RPMSIGTAG_DSA) 01176 continue; 01177 /*@switchbreak@*/ break; 01178 case RPMSIGTAG_MD5: 01179 if (nodigests) 01180 continue; 01181 /*@switchbreak@*/ break; 01182 default: 01183 continue; 01184 /*@notreached@*/ /*@switchbreak@*/ break; 01185 } 01186 01187 sigres = rpmVerifySignature(dig, result); 01188 01189 if (sigres) { 01190 failed = 1; 01191 if (rpmIsVerbose()) 01192 b = stpcpy( stpcpy( stpcpy(b, " "), result), "\n"); 01193 else 01194 switch ((rpmSigTag)she->tag) { 01195 case RPMSIGTAG_SIZE: 01196 b = stpcpy(b, "SIZE "); 01197 /*@switchbreak@*/ break; 01198 case RPMSIGTAG_SHA1: 01199 b = stpcpy(b, "SHA1 "); 01200 /*@switchbreak@*/ break; 01201 case RPMSIGTAG_MD5: 01202 b = stpcpy(b, "MD5 "); 01203 /*@switchbreak@*/ break; 01204 case RPMSIGTAG_RSA: 01205 b = stpcpy(b, "RSA "); 01206 /*@switchbreak@*/ break; 01207 case RPMSIGTAG_DSA: 01208 b = stpcpy(b, "(SHA1) DSA "); 01209 /*@switchbreak@*/ break; 01210 default: 01211 b = stpcpy(b, "?UnknownSignatureType? "); 01212 /*@switchbreak@*/ break; 01213 } 01214 } else { 01215 if (rpmIsVerbose()) 01216 b = stpcpy( stpcpy( stpcpy(b, " "), result), "\n"); 01217 else 01218 switch ((rpmSigTag)she->tag) { 01219 case RPMSIGTAG_SIZE: 01220 b = stpcpy(b, "size "); 01221 /*@switchbreak@*/ break; 01222 case RPMSIGTAG_SHA1: 01223 b = stpcpy(b, "sha1 "); 01224 /*@switchbreak@*/ break; 01225 case RPMSIGTAG_MD5: 01226 b = stpcpy(b, "md5 "); 01227 /*@switchbreak@*/ break; 01228 case RPMSIGTAG_RSA: 01229 b = stpcpy(b, "rsa "); 01230 /*@switchbreak@*/ break; 01231 case RPMSIGTAG_DSA: 01232 b = stpcpy(b, "(sha1) dsa "); 01233 /*@switchbreak@*/ break; 01234 default: 01235 b = stpcpy(b, "??? "); 01236 /*@switchbreak@*/ break; 01237 } 01238 } 01239 } 01240 hi = headerFini(hi); 01241 /* XXX clear the already free'd signature data. */ 01242 /*@-noeffect@*/ 01243 xx = pgpSetSig(dig, 0, 0, NULL, 0); 01244 /*@=noeffect@*/ 01245 01246 res += failed; 01247 01248 if (failed) { 01249 if (rpmIsVerbose()) { 01250 rpmlog(RPMLOG_NOTICE, "%s", buf); 01251 } else { 01252 rpmlog(RPMLOG_NOTICE, "%s%s%s%s%s%s%s%s\n", buf, 01253 _("NOT_OK"), 01254 (missingKeys[0] != '\0') ? _(" (MISSING KEYS:") : "", 01255 missingKeys, 01256 (missingKeys[0] != '\0') ? _(") ") : "", 01257 (untrustedKeys[0] != '\0') ? _(" (UNTRUSTED KEYS:") : "", 01258 untrustedKeys, 01259 (untrustedKeys[0] != '\0') ? _(")") : ""); 01260 01261 } 01262 } else { 01263 if (rpmIsVerbose()) { 01264 rpmlog(RPMLOG_NOTICE, "%s", buf); 01265 } else { 01266 rpmlog(RPMLOG_NOTICE, "%s%s%s%s%s%s%s%s\n", buf, 01267 _("OK"), 01268 (missingKeys[0] != '\0') ? _(" (MISSING KEYS:") : "", 01269 missingKeys, 01270 (missingKeys[0] != '\0') ? _(") ") : "", 01271 (untrustedKeys[0] != '\0') ? _(" (UNTRUSTED KEYS:") : "", 01272 untrustedKeys, 01273 (untrustedKeys[0] != '\0') ? _(")") : ""); 01274 } 01275 } 01276 01277 } 01278 01279 exit: 01280 rpmtsCleanDig(ts); 01281 (void)headerFree(sigh); 01282 sigh = NULL; 01283 return res; 01284 } 01285 01286 int rpmcliSign(rpmts ts, QVA_t qva, const char ** argv) 01287 /*@globals rpmioFtsOpts @*/ 01288 /*@modifies rpmioFtsOpts @*/ 01289 { 01290 int res = 0; 01291 01292 if (argv == NULL) return res; 01293 01294 switch (qva->qva_mode) { 01295 case RPMSIGN_CHK_SIGNATURE: 01296 break; 01297 case RPMSIGN_IMPORT_PUBKEY: 01298 return rpmcliImportPubkeys(ts, qva, argv); 01299 /*@notreached@*/ break; 01300 case RPMSIGN_NEW_SIGNATURE: 01301 case RPMSIGN_ADD_SIGNATURE: 01302 case RPMSIGN_DEL_SIGNATURE: 01303 return rpmReSign(ts, qva, argv); 01304 /*@notreached@*/ break; 01305 case RPMSIGN_NONE: 01306 default: 01307 return -1; 01308 /*@notreached@*/ break; 01309 } 01310 01311 { /* start-of-arg-iteration */ 01312 01313 int tag = (qva->qva_source == RPMQV_FTSWALK) 01314 ? RPMDBI_FTSWALK : RPMDBI_ARGLIST; 01315 rpmgi gi = rpmgiNew(ts, tag, NULL, 0); 01316 rpmgiFlags _giFlags = RPMGI_NONE; 01317 rpmRC rc; 01318 01319 if (rpmioFtsOpts == 0) 01320 rpmioFtsOpts = (FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOSTAT); 01321 rc = rpmgiSetArgs(gi, argv, rpmioFtsOpts, (_giFlags|RPMGI_NOHEADER)); 01322 while (rpmgiNext(gi) == RPMRC_OK) { 01323 const char * fn = rpmgiHdrPath(gi); 01324 FD_t fd; 01325 int xx; 01326 01327 fd = Fopen(fn, "r.fdio"); 01328 if (fd == NULL || Ferror(fd)) { 01329 rpmlog(RPMLOG_ERR, _("%s: open failed: %s\n"), 01330 fn, Fstrerror(fd)); 01331 res++; 01332 } else if (rpmVerifySignatures(qva, ts, fd, fn)) { 01333 res++; 01334 } 01335 01336 if (fd != NULL) { 01337 xx = Fclose(fd); 01338 } 01339 } 01340 01341 gi = rpmgiFree(gi); 01342 01343 } /* end-of-arg-iteration */ 01344 01345 return res; 01346 }