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