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