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