00001
00006 #include "system.h"
00007
00008 #include "rpmio_internal.h"
00009 #include <rpmcli.h>
00010
00011 #include "rpmdb.h"
00012
00013 #include "rpmts.h"
00014
00015 #include "rpmlead.h"
00016 #include "signature.h"
00017 #include "misc.h"
00018 #include "debug.h"
00019
00020
00021
00022
00023
00024
00025 int _print_pkts = 0;
00026
00029
00030 static int manageFile( FD_t *fdp,
00031 const char **fnp,
00032 int flags, int rc)
00033
00034
00035
00036 {
00037 const char *fn;
00038 FD_t fd;
00039
00040 if (fdp == NULL)
00041 return 1;
00042
00043
00044
00045 if (*fdp && (fnp == NULL || *fnp == NULL)) {
00046 (void) Fclose(*fdp);
00047 *fdp = NULL;
00048 return 0;
00049 }
00050
00051
00052 if (*fdp == NULL && fnp != NULL && *fnp != NULL) {
00053 fd = Fopen(*fnp, ((flags & O_WRONLY) ? "w.ufdio" : "r.ufdio"));
00054 if (fd == NULL || Ferror(fd)) {
00055 rpmError(RPMERR_OPEN, _("%s: open failed: %s\n"), *fnp,
00056 Fstrerror(fd));
00057 return 1;
00058 }
00059 *fdp = fd;
00060 return 0;
00061 }
00062
00063
00064 if (*fdp == NULL && (fnp == NULL || *fnp == NULL)) {
00065 fn = NULL;
00066 if (makeTempFile(NULL, (fnp ? &fn : NULL), &fd)) {
00067 rpmError(RPMERR_MAKETEMP, _("makeTempFile failed\n"));
00068 return 1;
00069 }
00070 if (fnp != NULL)
00071 *fnp = fn;
00072 *fdp = fdLink(fd, "manageFile return");
00073 fd = fdFree(fd, "manageFile return");
00074 return 0;
00075 }
00076
00077
00078
00079 if (*fdp != NULL && fnp != NULL && *fnp != NULL)
00080 return 0;
00081
00082
00083 return 1;
00084 }
00085
00086
00090
00091 static int copyFile(FD_t *sfdp, const char **sfnp,
00092 FD_t *tfdp, const char **tfnp)
00093
00094
00095
00096
00097 {
00098 unsigned char buf[BUFSIZ];
00099 ssize_t count;
00100 int rc = 1;
00101
00102 if (manageFile(sfdp, sfnp, O_RDONLY, 0))
00103 goto exit;
00104 if (manageFile(tfdp, tfnp, O_WRONLY|O_CREAT|O_TRUNC, 0))
00105 goto exit;
00106
00107 while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), *sfdp)) > 0)
00108 {
00109 if (Fwrite(buf, sizeof(buf[0]), count, *tfdp) != count) {
00110 rpmError(RPMERR_FWRITE, _("%s: Fwrite failed: %s\n"), *tfnp,
00111 Fstrerror(*tfdp));
00112 goto exit;
00113 }
00114 }
00115 if (count < 0) {
00116 rpmError(RPMERR_FREAD, _("%s: Fread failed: %s\n"), *sfnp, Fstrerror(*sfdp));
00117 goto exit;
00118 }
00119
00120 rc = 0;
00121
00122 exit:
00123 if (*sfdp) (void) manageFile(sfdp, NULL, 0, rc);
00124 if (*tfdp) (void) manageFile(tfdp, NULL, 0, rc);
00125 return rc;
00126 }
00127
00128
00136 static int getSignid(Header sig, int sigtag, unsigned char * signid)
00137
00138
00139 {
00140 void * pkt = NULL;
00141 int_32 pkttyp = 0;
00142 int_32 pktlen = 0;
00143 int rc = 1;
00144
00145 if (headerGetEntry(sig, sigtag, &pkttyp, &pkt, &pktlen) && pkt != NULL) {
00146 pgpDig dig = pgpNewDig();
00147
00148 if (!pgpPrtPkts(pkt, pktlen, dig, 0)) {
00149
00150 memcpy(signid, dig->signature.signid, sizeof(dig->signature.signid));
00151
00152 rc = 0;
00153 }
00154
00155 dig = pgpFreeDig(dig);
00156 }
00157 pkt = headerFreeData(pkt, pkttyp);
00158 return rc;
00159 }
00160
00168 static int rpmReSign( rpmts ts,
00169 QVA_t qva, const char ** argv)
00170
00171
00172
00173
00174 {
00175 FD_t fd = NULL;
00176 FD_t ofd = NULL;
00177 struct rpmlead lead, *l = &lead;
00178 int_32 sigtag;
00179 const char *rpm, *trpm;
00180 const char *sigtarget = NULL;
00181 char tmprpm[1024+1];
00182 Header sigh = NULL;
00183 const char * msg;
00184 void * uh = NULL;
00185 int_32 uht, uhc;
00186 int res = EXIT_FAILURE;
00187 rpmRC rc;
00188 int xx;
00189
00190 tmprpm[0] = '\0';
00191
00192
00193 if (argv)
00194 while ((rpm = *argv++) != NULL)
00195
00196 {
00197
00198 fprintf(stdout, "%s:\n", rpm);
00199
00200 if (manageFile(&fd, &rpm, O_RDONLY, 0))
00201 goto exit;
00202
00203
00204 memset(l, 0, sizeof(*l));
00205
00206 rc = readLead(fd, l);
00207 if (rc != RPMRC_OK) {
00208 rpmError(RPMERR_READLEAD, _("%s: not an rpm package\n"), rpm);
00209 goto exit;
00210 }
00211 switch (l->major) {
00212 case 1:
00213 rpmError(RPMERR_BADSIGTYPE, _("%s: Can't sign v1 packaging\n"), rpm);
00214 goto exit;
00215 break;
00216 case 2:
00217 rpmError(RPMERR_BADSIGTYPE, _("%s: Can't re-sign v2 packaging\n"), rpm);
00218 goto exit;
00219 break;
00220 default:
00221 break;
00222 }
00223
00224 msg = NULL;
00225 rc = rpmReadSignature(fd, &sigh, l->signature_type, &msg);
00226 switch (rc) {
00227 default:
00228 rpmError(RPMERR_SIGGEN, _("%s: rpmReadSignature failed: %s"), rpm,
00229 (msg && *msg ? msg : "\n"));
00230 msg = _free(msg);
00231 goto exit;
00232 break;
00233 case RPMRC_OK:
00234 if (sigh == NULL) {
00235 rpmError(RPMERR_SIGGEN, _("%s: No signature available\n"), rpm);
00236 goto exit;
00237 }
00238 break;
00239 }
00240 msg = _free(msg);
00241
00242
00243
00244 if (copyFile(&fd, &rpm, &ofd, &sigtarget))
00245 goto exit;
00246
00247
00248
00249
00250 if (headerGetEntry(sigh, RPMTAG_HEADERSIGNATURES, &uht, &uh, &uhc)) {
00251 HeaderIterator hi;
00252 int_32 tag, type, count;
00253 hPTR_t ptr;
00254 Header oh;
00255 Header nh;
00256
00257 nh = headerNew();
00258 if (nh == NULL) {
00259 uh = headerFreeData(uh, uht);
00260 goto exit;
00261 }
00262
00263 oh = headerCopyLoad(uh);
00264 for (hi = headerInitIterator(oh);
00265 headerNextIterator(hi, &tag, &type, &ptr, &count);
00266 ptr = headerFreeData(ptr, type))
00267 {
00268 if (ptr)
00269 xx = headerAddEntry(nh, tag, type, ptr, count);
00270 }
00271 hi = headerFreeIterator(hi);
00272 oh = headerFree(oh);
00273
00274 sigh = headerFree(sigh);
00275 sigh = headerLink(nh);
00276 nh = headerFree(nh);
00277 }
00278
00279
00280 xx = headerRemoveEntry(sigh, RPMSIGTAG_LEMD5_1);
00281 xx = headerRemoveEntry(sigh, RPMSIGTAG_LEMD5_2);
00282 xx = headerRemoveEntry(sigh, RPMSIGTAG_BADSHA1_1);
00283 xx = headerRemoveEntry(sigh, RPMSIGTAG_BADSHA1_2);
00284
00285
00286 xx = headerRemoveEntry(sigh, RPMSIGTAG_SIZE);
00287 xx = rpmAddSignature(sigh, sigtarget, RPMSIGTAG_SIZE, qva->passPhrase);
00288 xx = headerRemoveEntry(sigh, RPMSIGTAG_MD5);
00289 xx = rpmAddSignature(sigh, sigtarget, RPMSIGTAG_MD5, qva->passPhrase);
00290 xx = headerRemoveEntry(sigh, RPMSIGTAG_SHA1);
00291 xx = rpmAddSignature(sigh, sigtarget, RPMSIGTAG_SHA1, qva->passPhrase);
00292
00293
00294 if ((sigtag = rpmLookupSignatureType(RPMLOOKUPSIG_QUERY)) > 0) {
00295 unsigned char oldsignid[8], newsignid[8];
00296
00297
00298 memset(oldsignid, 0, sizeof(oldsignid));
00299 xx = getSignid(sigh, sigtag, oldsignid);
00300
00301 switch (sigtag) {
00302 case RPMSIGTAG_GPG:
00303 xx = headerRemoveEntry(sigh, RPMSIGTAG_DSA);
00304
00305 case RPMSIGTAG_PGP5:
00306 case RPMSIGTAG_PGP:
00307 xx = headerRemoveEntry(sigh, RPMSIGTAG_RSA);
00308 break;
00309 }
00310
00311 xx = headerRemoveEntry(sigh, sigtag);
00312 xx = rpmAddSignature(sigh, sigtarget, sigtag, qva->passPhrase);
00313
00314
00315 memset(newsignid, 0, sizeof(newsignid));
00316 if (memcmp(oldsignid, newsignid, sizeof(oldsignid))) {
00317
00318
00319 xx = getSignid(sigh, sigtag, newsignid);
00320
00321
00322 if (!memcmp(oldsignid, newsignid, sizeof(oldsignid))) {
00323
00324 rpmMessage(RPMMESS_WARNING,
00325 _("%s: was already signed by key ID %s, skipping\n"),
00326 rpm, pgpHexStr(newsignid+4, sizeof(newsignid)-4));
00327
00328
00329 xx = unlink(sigtarget);
00330 sigtarget = _free(sigtarget);
00331 continue;
00332 }
00333 }
00334
00335 }
00336
00337
00338 sigh = headerReload(sigh, RPMTAG_HEADERSIGNATURES);
00339 if (sigh == NULL)
00340 goto exit;
00341
00342
00343
00344 strcpy(tmprpm, rpm);
00345 strcat(tmprpm, ".XXXXXX");
00346
00347 (void) mktemp(tmprpm);
00348 trpm = tmprpm;
00349
00350 if (manageFile(&ofd, &trpm, O_WRONLY|O_CREAT|O_TRUNC, 0))
00351 goto exit;
00352
00353 l->signature_type = RPMSIGTYPE_HEADERSIG;
00354 rc = writeLead(ofd, l);
00355 if (rc != RPMRC_OK) {
00356 rpmError(RPMERR_WRITELEAD, _("%s: writeLead failed: %s\n"), trpm,
00357 Fstrerror(ofd));
00358 goto exit;
00359 }
00360
00361 if (rpmWriteSignature(ofd, sigh)) {
00362 rpmError(RPMERR_SIGGEN, _("%s: rpmWriteSignature failed: %s\n"), trpm,
00363 Fstrerror(ofd));
00364 goto exit;
00365 }
00366
00367
00368
00369 if (copyFile(&fd, &sigtarget, &ofd, &trpm))
00370 goto exit;
00371
00372
00373
00374
00375 xx = unlink(rpm);
00376 xx = rename(trpm, rpm);
00377 tmprpm[0] = '\0';
00378
00379
00380 xx = unlink(sigtarget);
00381 sigtarget = _free(sigtarget);
00382 }
00383
00384
00385 res = 0;
00386
00387 exit:
00388 if (fd) (void) manageFile(&fd, NULL, 0, res);
00389 if (ofd) (void) manageFile(&ofd, NULL, 0, res);
00390
00391 sigh = rpmFreeSignature(sigh);
00392
00393 if (sigtarget) {
00394 xx = unlink(sigtarget);
00395 sigtarget = _free(sigtarget);
00396 }
00397 if (tmprpm[0] != '\0') {
00398 xx = unlink(tmprpm);
00399 tmprpm[0] = '\0';
00400 }
00401
00402 return res;
00403 }
00404
00405 rpmRC rpmcliImportPubkey(const rpmts ts, const unsigned char * pkt, ssize_t pktlen)
00406 {
00407 static unsigned char zeros[] =
00408 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
00409 const char * afmt = "%{pubkeys:armor}";
00410 const char * group = "Public Keys";
00411 const char * license = "pubkey";
00412 const char * buildhost = "localhost";
00413 int_32 pflags = (RPMSENSE_KEYRING|RPMSENSE_EQUAL);
00414 int_32 zero = 0;
00415 pgpDig dig = NULL;
00416 pgpDigParams pubp = NULL;
00417 const char * d = NULL;
00418 const char * enc = NULL;
00419 const char * n = NULL;
00420 const char * u = NULL;
00421 const char * v = NULL;
00422 const char * r = NULL;
00423 const char * evr = NULL;
00424 Header h = NULL;
00425 rpmRC rc = RPMRC_FAIL;
00426 char * t;
00427 int xx;
00428
00429 if (pkt == NULL || pktlen <= 0)
00430 return RPMRC_FAIL;
00431 if (rpmtsOpenDB(ts, (O_RDWR|O_CREAT)))
00432 return RPMRC_FAIL;
00433
00434 if ((enc = b64encode(pkt, pktlen)) == NULL)
00435 goto exit;
00436
00437 dig = pgpNewDig();
00438
00439
00440 (void) pgpPrtPkts(pkt, pktlen, dig, 0);
00441 pubp = &dig->pubkey;
00442
00443 if (!memcmp(pubp->signid, zeros, sizeof(pubp->signid))
00444 || !memcmp(pubp->time, zeros, sizeof(pubp->time))
00445 || pubp->userid == NULL)
00446 goto exit;
00447
00448
00449 v = t = xmalloc(16+1);
00450 t = stpcpy(t, pgpHexStr(pubp->signid, sizeof(pubp->signid)));
00451
00452 r = t = xmalloc(8+1);
00453 t = stpcpy(t, pgpHexStr(pubp->time, sizeof(pubp->time)));
00454
00455 n = t = xmalloc(sizeof("gpg()")+8);
00456 t = stpcpy( stpcpy( stpcpy(t, "gpg("), v+8), ")");
00457
00458
00459 u = t = xmalloc(sizeof("gpg()")+strlen(pubp->userid));
00460 t = stpcpy( stpcpy( stpcpy(t, "gpg("), pubp->userid), ")");
00461
00462
00463 evr = t = xmalloc(sizeof("4X:-")+strlen(v)+strlen(r));
00464 t = stpcpy(t, (pubp->version == 4 ? "4:" : "3:"));
00465 t = stpcpy( stpcpy( stpcpy(t, v), "-"), r);
00466
00467
00468
00469
00470
00471 h = headerNew();
00472
00473 xx = headerAddOrAppendEntry(h, RPMTAG_PUBKEYS,
00474 RPM_STRING_ARRAY_TYPE, &enc, 1);
00475
00476 d = headerSprintf(h, afmt, rpmTagTable, rpmHeaderFormats, NULL);
00477 if (d == NULL)
00478 goto exit;
00479
00480 xx = headerAddEntry(h, RPMTAG_NAME, RPM_STRING_TYPE, "gpg-pubkey", 1);
00481 xx = headerAddEntry(h, RPMTAG_VERSION, RPM_STRING_TYPE, v+8, 1);
00482 xx = headerAddEntry(h, RPMTAG_RELEASE, RPM_STRING_TYPE, r, 1);
00483 xx = headerAddEntry(h, RPMTAG_DESCRIPTION, RPM_STRING_TYPE, d, 1);
00484 xx = headerAddEntry(h, RPMTAG_GROUP, RPM_STRING_TYPE, group, 1);
00485 xx = headerAddEntry(h, RPMTAG_LICENSE, RPM_STRING_TYPE, license, 1);
00486 xx = headerAddEntry(h, RPMTAG_SUMMARY, RPM_STRING_TYPE, u, 1);
00487
00488 xx = headerAddEntry(h, RPMTAG_SIZE, RPM_INT32_TYPE, &zero, 1);
00489
00490 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDENAME,
00491 RPM_STRING_ARRAY_TYPE, &u, 1);
00492 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEVERSION,
00493 RPM_STRING_ARRAY_TYPE, &evr, 1);
00494 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEFLAGS,
00495 RPM_INT32_TYPE, &pflags, 1);
00496
00497 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDENAME,
00498 RPM_STRING_ARRAY_TYPE, &n, 1);
00499 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEVERSION,
00500 RPM_STRING_ARRAY_TYPE, &evr, 1);
00501 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEFLAGS,
00502 RPM_INT32_TYPE, &pflags, 1);
00503
00504 xx = headerAddEntry(h, RPMTAG_RPMVERSION, RPM_STRING_TYPE, RPMVERSION, 1);
00505
00506
00507 xx = headerAddEntry(h, RPMTAG_BUILDHOST, RPM_STRING_TYPE, buildhost, 1);
00508 { int_32 tid = rpmtsGetTid(ts);
00509 xx = headerAddEntry(h, RPMTAG_INSTALLTIME, RPM_INT32_TYPE, &tid, 1);
00510
00511 xx = headerAddEntry(h, RPMTAG_BUILDTIME, RPM_INT32_TYPE, &tid, 1);
00512 }
00513
00514 #ifdef NOTYET
00515
00516 xx = headerAddEntry(h, RPMTAG_SOURCERPM, RPM_STRING_TYPE, fn, 1);
00517 #endif
00518
00519
00520 xx = rpmdbAdd(rpmtsGetRdb(ts), rpmtsGetTid(ts), h, NULL, NULL);
00521 if (xx != 0)
00522 goto exit;
00523 rc = RPMRC_OK;
00524
00525 exit:
00526
00527 h = headerFree(h);
00528 dig = pgpFreeDig(dig);
00529 n = _free(n);
00530 u = _free(u);
00531 v = _free(v);
00532 r = _free(r);
00533 evr = _free(evr);
00534 enc = _free(enc);
00535 d = _free(d);
00536
00537 return rc;
00538 }
00539
00548 static int rpmcliImportPubkeys(const rpmts ts,
00549 QVA_t qva,
00550 const char ** argv)
00551
00552
00553
00554
00555 {
00556 const char * fn;
00557 const unsigned char * pkt = NULL;
00558 ssize_t pktlen = 0;
00559 int res = 0;
00560 rpmRC rpmrc;
00561 int rc;
00562
00563 if (argv == NULL) return res;
00564
00565
00566
00567 while ((fn = *argv++) != NULL) {
00568
00569
00570 rpmtsClean(ts);
00571 pkt = _free(pkt);
00572
00573
00574 if ((rc = pgpReadPkts(fn, &pkt, &pktlen)) <= 0) {
00575 rpmError(RPMERR_IMPORT, _("%s: import read failed.\n"), fn);
00576 res++;
00577 continue;
00578 }
00579 if (rc != PGPARMOR_PUBKEY) {
00580 rpmError(RPMERR_IMPORT, _("%s: not an armored public key.\n"), fn);
00581 res++;
00582 continue;
00583 }
00584
00585
00586 if ((rpmrc = rpmcliImportPubkey(ts, pkt, pktlen)) != RPMRC_OK) {
00587 rpmError(RPMERR_IMPORT, _("%s: import failed.\n"), fn);
00588 res++;
00589 continue;
00590 }
00591
00592 }
00593
00594
00595 rpmtsClean(ts);
00596 pkt = _free(pkt);
00597 return res;
00598 }
00599
00600
00601 static unsigned char header_magic[8] = {
00602 0x8e, 0xad, 0xe8, 0x01, 0x00, 0x00, 0x00, 0x00
00603 };
00604
00608 static int readFile(FD_t fd, const char * fn, pgpDig dig)
00609
00610
00611 {
00612 unsigned char buf[4*BUFSIZ];
00613 ssize_t count;
00614 int rc = 1;
00615 int i;
00616
00617 dig->nbytes = 0;
00618
00619
00620 { Header h = headerRead(fd, HEADER_MAGIC_YES);
00621 if (h == NULL) {
00622 rpmError(RPMERR_FREAD, _("%s: headerRead failed\n"), fn);
00623 goto exit;
00624 }
00625
00626 dig->nbytes += headerSizeof(h, HEADER_MAGIC_YES);
00627
00628 if (headerIsEntry(h, RPMTAG_HEADERIMMUTABLE)) {
00629 void * uh;
00630 int_32 uht, uhc;
00631
00632 if (!headerGetEntry(h, RPMTAG_HEADERIMMUTABLE, &uht, &uh, &uhc)
00633 || uh == NULL)
00634 {
00635 h = headerFree(h);
00636 rpmError(RPMERR_FREAD, _("%s: headerGetEntry failed\n"), fn);
00637 goto exit;
00638 }
00639 dig->hdrsha1ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
00640 (void) rpmDigestUpdate(dig->hdrsha1ctx, header_magic, sizeof(header_magic));
00641 (void) rpmDigestUpdate(dig->hdrsha1ctx, uh, uhc);
00642 uh = headerFreeData(uh, uht);
00643 }
00644 h = headerFree(h);
00645 }
00646
00647
00648 while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), fd)) > 0)
00649 dig->nbytes += count;
00650 if (count < 0) {
00651 rpmError(RPMERR_FREAD, _("%s: Fread failed: %s\n"), fn, Fstrerror(fd));
00652 goto exit;
00653 }
00654
00655
00656 for (i = fd->ndigests - 1; i >= 0; i--) {
00657 FDDIGEST_t fddig = fd->digests + i;
00658 if (fddig->hashctx == NULL)
00659 continue;
00660 if (fddig->hashalgo == PGPHASHALGO_MD5) {
00661 assert(dig->md5ctx == NULL);
00662 dig->md5ctx = fddig->hashctx;
00663 fddig->hashctx = NULL;
00664 continue;
00665 }
00666 if (fddig->hashalgo == PGPHASHALGO_SHA1) {
00667 assert(dig->sha1ctx == NULL);
00668 dig->sha1ctx = fddig->hashctx;
00669 fddig->hashctx = NULL;
00670 continue;
00671 }
00672 }
00673
00674 rc = 0;
00675
00676 exit:
00677 return rc;
00678 }
00679
00680 int rpmVerifySignatures(QVA_t qva, rpmts ts, FD_t fd,
00681 const char * fn)
00682 {
00683 int res2, res3;
00684 struct rpmlead lead, *l = &lead;
00685 char result[1024];
00686 char buf[8192], * b;
00687 char missingKeys[7164], * m;
00688 char untrustedKeys[7164], * u;
00689 int_32 sigtag;
00690 int_32 sigtype;
00691 const void * sig;
00692 pgpDig dig;
00693 pgpDigParams sigp;
00694 int_32 siglen;
00695 Header sigh = NULL;
00696 HeaderIterator hi;
00697 const char * msg;
00698 int res = 0;
00699 int xx;
00700 rpmRC rc;
00701 int nodigests = !(qva->qva_flags & VERIFY_DIGEST);
00702 int nosignatures = !(qva->qva_flags & VERIFY_SIGNATURE);
00703
00704 {
00705
00706 memset(l, 0, sizeof(*l));
00707
00708 rc = readLead(fd, l);
00709 if (rc != RPMRC_OK) {
00710 rpmError(RPMERR_READLEAD, _("%s: not an rpm package\n"), fn);
00711 res++;
00712 goto exit;
00713 }
00714 switch (l->major) {
00715 case 1:
00716 rpmError(RPMERR_BADSIGTYPE, _("%s: No signature available (v1.0 RPM)\n"), fn);
00717 res++;
00718 goto exit;
00719 break;
00720 default:
00721 break;
00722 }
00723
00724 msg = NULL;
00725 rc = rpmReadSignature(fd, &sigh, l->signature_type, &msg);
00726 switch (rc) {
00727 default:
00728 rpmError(RPMERR_SIGGEN, _("%s: rpmReadSignature failed: %s"), fn,
00729 (msg && *msg ? msg : "\n"));
00730 msg = _free(msg);
00731 res++;
00732 goto exit;
00733 break;
00734 case RPMRC_OK:
00735 if (sigh == NULL) {
00736 rpmError(RPMERR_SIGGEN, _("%s: No signature available\n"), fn);
00737 res++;
00738 goto exit;
00739 }
00740 break;
00741 }
00742 msg = _free(msg);
00743
00744
00745 sigtag = 0;
00746 if (sigtag == 0 && !nosignatures) {
00747 if (headerIsEntry(sigh, RPMSIGTAG_DSA))
00748 sigtag = RPMSIGTAG_DSA;
00749 else if (headerIsEntry(sigh, RPMSIGTAG_RSA))
00750 sigtag = RPMSIGTAG_RSA;
00751 else if (headerIsEntry(sigh, RPMSIGTAG_GPG))
00752 sigtag = RPMSIGTAG_GPG;
00753 else if (headerIsEntry(sigh, RPMSIGTAG_PGP))
00754 sigtag = RPMSIGTAG_PGP;
00755 }
00756 if (sigtag == 0 && !nodigests) {
00757 if (headerIsEntry(sigh, RPMSIGTAG_MD5))
00758 sigtag = RPMSIGTAG_MD5;
00759 else if (headerIsEntry(sigh, RPMSIGTAG_SHA1))
00760 sigtag = RPMSIGTAG_SHA1;
00761 }
00762
00763 if (headerIsEntry(sigh, RPMSIGTAG_PGP)
00764 || headerIsEntry(sigh, RPMSIGTAG_PGP5)
00765 || headerIsEntry(sigh, RPMSIGTAG_MD5))
00766 fdInitDigest(fd, PGPHASHALGO_MD5, 0);
00767 if (headerIsEntry(sigh, RPMSIGTAG_GPG))
00768 fdInitDigest(fd, PGPHASHALGO_SHA1, 0);
00769
00770 dig = rpmtsDig(ts);
00771 sigp = rpmtsSignature(ts);
00772
00773
00774 if (dig == NULL || sigp == NULL || readFile(fd, fn, dig)) {
00775 res++;
00776 goto exit;
00777 }
00778
00779 res2 = 0;
00780 b = buf; *b = '\0';
00781 m = missingKeys; *m = '\0';
00782 u = untrustedKeys; *u = '\0';
00783 sprintf(b, "%s:%c", fn, (rpmIsVerbose() ? '\n' : ' ') );
00784 b += strlen(b);
00785
00786 for (hi = headerInitIterator(sigh);
00787 headerNextIterator(hi, &sigtag, &sigtype, &sig, &siglen) != 0;
00788 (void) rpmtsSetSig(ts, sigtag, sigtype, NULL, siglen))
00789 {
00790
00791 if (sig == NULL)
00792 continue;
00793
00794 (void) rpmtsSetSig(ts, sigtag, sigtype, sig, siglen);
00795
00796
00797 pgpCleanDig(dig);
00798
00799 switch (sigtag) {
00800 case RPMSIGTAG_RSA:
00801 case RPMSIGTAG_DSA:
00802 case RPMSIGTAG_GPG:
00803 case RPMSIGTAG_PGP5:
00804 case RPMSIGTAG_PGP:
00805 if (nosignatures)
00806 continue;
00807 xx = pgpPrtPkts(sig, siglen, dig,
00808 (_print_pkts & rpmIsDebug()));
00809
00810
00811 if (sigp->version != 3) {
00812 rpmError(RPMERR_SIGVFY,
00813 _("only V3 signatures can be verified, skipping V%u signature\n"),
00814 sigp->version);
00815 continue;
00816 }
00817 break;
00818 case RPMSIGTAG_SHA1:
00819 if (nodigests)
00820 continue;
00821
00822 if (!nosignatures && sigtag == RPMSIGTAG_DSA)
00823 continue;
00824 break;
00825 case RPMSIGTAG_LEMD5_2:
00826 case RPMSIGTAG_LEMD5_1:
00827 case RPMSIGTAG_MD5:
00828 if (nodigests)
00829 continue;
00830
00831
00832
00833
00834 if (!nosignatures && sigtag == RPMSIGTAG_PGP)
00835 continue;
00836 break;
00837 default:
00838 continue;
00839 break;
00840 }
00841
00842 res3 = rpmVerifySignature(ts, result);
00843
00844
00845 if (res3) {
00846 if (rpmIsVerbose()) {
00847 b = stpcpy(b, " ");
00848 b = stpcpy(b, result);
00849 res2 = 1;
00850 } else {
00851 char *tempKey;
00852 switch (sigtag) {
00853 case RPMSIGTAG_SIZE:
00854 b = stpcpy(b, "SIZE ");
00855 res2 = 1;
00856 break;
00857 case RPMSIGTAG_SHA1:
00858 b = stpcpy(b, "SHA1 ");
00859 res2 = 1;
00860 break;
00861 case RPMSIGTAG_LEMD5_2:
00862 case RPMSIGTAG_LEMD5_1:
00863 case RPMSIGTAG_MD5:
00864 b = stpcpy(b, "MD5 ");
00865 res2 = 1;
00866 break;
00867 case RPMSIGTAG_RSA:
00868 b = stpcpy(b, "RSA ");
00869 res2 = 1;
00870 break;
00871 case RPMSIGTAG_PGP5:
00872 case RPMSIGTAG_PGP:
00873 switch (res3) {
00874 case RPMRC_NOKEY:
00875 res2 = 1;
00876
00877 case RPMRC_NOTTRUSTED:
00878 { int offset = 6;
00879 b = stpcpy(b, "(MD5) (PGP) ");
00880 tempKey = strstr(result, "ey ID");
00881 if (tempKey == NULL) {
00882 tempKey = strstr(result, "keyid:");
00883 offset = 9;
00884 }
00885 if (tempKey) {
00886 if (res3 == RPMRC_NOKEY) {
00887 m = stpcpy(m, " PGP#");
00888 m = stpncpy(m, tempKey + offset, 8);
00889 *m = '\0';
00890 } else {
00891 u = stpcpy(u, " PGP#");
00892 u = stpncpy(u, tempKey + offset, 8);
00893 *u = '\0';
00894 }
00895 }
00896 } break;
00897 default:
00898 b = stpcpy(b, "MD5 PGP ");
00899 res2 = 1;
00900 break;
00901 }
00902 break;
00903 case RPMSIGTAG_DSA:
00904 b = stpcpy(b, "(SHA1) DSA ");
00905 res2 = 1;
00906 break;
00907 case RPMSIGTAG_GPG:
00908
00909 switch (res3) {
00910 case RPMRC_NOKEY:
00911 b = stpcpy(b, "(GPG) ");
00912 m = stpcpy(m, " GPG#");
00913 tempKey = strstr(result, "ey ID");
00914 if (tempKey) {
00915 m = stpncpy(m, tempKey+6, 8);
00916 *m = '\0';
00917 }
00918 res2 = 1;
00919 break;
00920 default:
00921 b = stpcpy(b, "GPG ");
00922 res2 = 1;
00923 break;
00924 }
00925 break;
00926 default:
00927 b = stpcpy(b, "?UnknownSignatureType? ");
00928 res2 = 1;
00929 break;
00930 }
00931 }
00932 } else {
00933 if (rpmIsVerbose()) {
00934 b = stpcpy(b, " ");
00935 b = stpcpy(b, result);
00936 } else {
00937 switch (sigtag) {
00938 case RPMSIGTAG_SIZE:
00939 b = stpcpy(b, "size ");
00940 break;
00941 case RPMSIGTAG_SHA1:
00942 b = stpcpy(b, "sha1 ");
00943 break;
00944 case RPMSIGTAG_LEMD5_2:
00945 case RPMSIGTAG_LEMD5_1:
00946 case RPMSIGTAG_MD5:
00947 b = stpcpy(b, "md5 ");
00948 break;
00949 case RPMSIGTAG_RSA:
00950 b = stpcpy(b, "rsa ");
00951 break;
00952 case RPMSIGTAG_PGP5:
00953 case RPMSIGTAG_PGP:
00954 b = stpcpy(b, "(md5) pgp ");
00955 break;
00956 case RPMSIGTAG_DSA:
00957 b = stpcpy(b, "(sha1) dsa ");
00958 break;
00959 case RPMSIGTAG_GPG:
00960 b = stpcpy(b, "gpg ");
00961 break;
00962 default:
00963 b = stpcpy(b, "??? ");
00964 break;
00965 }
00966 }
00967 }
00968
00969 }
00970 hi = headerFreeIterator(hi);
00971
00972 res += res2;
00973
00974 if (res2) {
00975 if (rpmIsVerbose()) {
00976 rpmError(RPMERR_SIGVFY, "%s", buf);
00977 } else {
00978 rpmError(RPMERR_SIGVFY, "%s%s%s%s%s%s%s%s\n", buf,
00979 _("NOT OK"),
00980 (missingKeys[0] != '\0') ? _(" (MISSING KEYS:") : "",
00981 missingKeys,
00982 (missingKeys[0] != '\0') ? _(") ") : "",
00983 (untrustedKeys[0] != '\0') ? _(" (UNTRUSTED KEYS:") : "",
00984 untrustedKeys,
00985 (untrustedKeys[0] != '\0') ? _(")") : "");
00986
00987 }
00988 } else {
00989 if (rpmIsVerbose()) {
00990 rpmError(RPMERR_SIGVFY, "%s", buf);
00991 } else {
00992 rpmError(RPMERR_SIGVFY, "%s%s%s%s%s%s%s%s\n", buf,
00993 _("OK"),
00994 (missingKeys[0] != '\0') ? _(" (MISSING KEYS:") : "",
00995 missingKeys,
00996 (missingKeys[0] != '\0') ? _(") ") : "",
00997 (untrustedKeys[0] != '\0') ? _(" (UNTRUSTED KEYS:") : "",
00998 untrustedKeys,
00999 (untrustedKeys[0] != '\0') ? _(")") : "");
01000 }
01001 }
01002
01003 }
01004
01005 exit:
01006 sigh = rpmFreeSignature(sigh);
01007 rpmtsCleanDig(ts);
01008 return res;
01009 }
01010
01011 int rpmcliSign(rpmts ts, QVA_t qva, const char ** argv)
01012 {
01013 const char * arg;
01014 int res = 0;
01015 int xx;
01016
01017 if (argv == NULL) return res;
01018
01019 switch (qva->qva_mode) {
01020 case RPMSIGN_CHK_SIGNATURE:
01021 break;
01022 case RPMSIGN_IMPORT_PUBKEY:
01023 return rpmcliImportPubkeys(ts, qva, argv);
01024 break;
01025 case RPMSIGN_NEW_SIGNATURE:
01026 case RPMSIGN_ADD_SIGNATURE:
01027 return rpmReSign(ts, qva, argv);
01028 break;
01029 case RPMSIGN_NONE:
01030 default:
01031 return -1;
01032 break;
01033 }
01034
01035 while ((arg = *argv++) != NULL) {
01036 FD_t fd;
01037
01038 if ((fd = Fopen(arg, "r.ufdio")) == NULL
01039 || Ferror(fd)
01040 || rpmVerifySignatures(qva, ts, fd, arg))
01041 res++;
01042
01043 if (fd != NULL) xx = Fclose(fd);
01044 }
01045
01046 return res;
01047 }