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