00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "system.h"
00015
00016 #if HAVE_ASM_BYTEORDER_H
00017 #include <asm/byteorder.h>
00018 #endif
00019
00020 #include <rpmlib.h>
00021 #include <rpmmacro.h>
00022
00023 #include "md5.h"
00024 #include "misc.h"
00025 #include "rpmlead.h"
00026 #include "signature.h"
00027 #include "debug.h"
00028
00029
00030
00031 typedef unsigned char byte;
00032
00033 typedef int (*md5func)(const char * fn, byte * digest);
00034
00035 int rpmLookupSignatureType(int action)
00036 {
00037 static int disabled = 0;
00038 int rc = 0;
00039
00040 switch (action) {
00041 case RPMLOOKUPSIG_DISABLE:
00042 disabled = -2;
00043 break;
00044 case RPMLOOKUPSIG_ENABLE:
00045 disabled = 0;
00046
00047
00048 case RPMLOOKUPSIG_QUERY:
00049 if (disabled)
00050 break;
00051 { const char *name = rpmExpand("%{_signature}", NULL);
00052 if (!(name && *name != '%'))
00053 rc = 0;
00054 else if (!xstrcasecmp(name, "none"))
00055 rc = 0;
00056 else if (!xstrcasecmp(name, "pgp"))
00057 rc = RPMSIGTAG_PGP;
00058 else if (!xstrcasecmp(name, "pgp5"))
00059 rc = RPMSIGTAG_PGP;
00060 else if (!xstrcasecmp(name, "gpg"))
00061 rc = RPMSIGTAG_GPG;
00062 else
00063 rc = -1;
00064 free((void *)name);
00065 } break;
00066 }
00067 return rc;
00068 }
00069
00070
00071
00072
00073 const char * rpmDetectPGPVersion(pgpVersion *pgpVer)
00074 {
00075
00076
00077
00078
00079 static pgpVersion saved_pgp_version = PGP_UNKNOWN;
00080 const char *pgpbin = rpmGetPath("%{_pgpbin}", NULL);
00081
00082 if (saved_pgp_version == PGP_UNKNOWN) {
00083 char *pgpvbin;
00084 struct stat st;
00085
00086 if (!(pgpbin && pgpbin[0] != '%')) {
00087 if (pgpbin) free((void *)pgpbin);
00088 saved_pgp_version = -1;
00089 return NULL;
00090 }
00091 pgpvbin = (char *)alloca(strlen(pgpbin) + sizeof("v"));
00092 (void)stpcpy(stpcpy(pgpvbin, pgpbin), "v");
00093
00094 if (stat(pgpvbin, &st) == 0)
00095 saved_pgp_version = PGP_5;
00096 else if (stat(pgpbin, &st) == 0)
00097 saved_pgp_version = PGP_2;
00098 else
00099 saved_pgp_version = PGP_NOTDETECTED;
00100 }
00101
00102 if (pgpbin && pgpVer)
00103 *pgpVer = saved_pgp_version;
00104 return pgpbin;
00105 }
00106
00107 static inline int checkSize(FD_t fd, int siglen, int pad, int datalen)
00108 {
00109 struct stat st;
00110
00111 fstat(Fileno(fd), &st);
00112
00113 if (!S_ISREG(st.st_mode)) {
00114 rpmMessage(RPMMESS_DEBUG,
00115 _("file is not regular -- skipping size check\n"));
00116 return 0;
00117 }
00118 rpmMessage(RPMMESS_DEBUG,
00119 _("Expected size: %12d = lead(%d)+sigs(%d)+pad(%d)+data(%d)\n"),
00120 sizeof(struct rpmlead)+siglen+pad+datalen,
00121 sizeof(struct rpmlead), siglen, pad, datalen);
00122 rpmMessage(RPMMESS_DEBUG,
00123 _(" Actual size: %12d\n"), st.st_size);
00124
00125 return ((sizeof(struct rpmlead) + siglen + pad + datalen) - st.st_size);
00126 }
00127
00128 int rpmReadSignature(FD_t fd, Header *headerp, short sigType)
00129 {
00130 byte buf[2048];
00131 int sigSize, pad;
00132 int_32 type, count;
00133 int_32 *archSize;
00134 Header h = NULL;
00135 int nb;
00136 int rc = 1;
00137
00138 if (headerp)
00139 *headerp = NULL;
00140
00141 switch (sigType) {
00142 case RPMSIG_NONE:
00143 rpmMessage(RPMMESS_DEBUG, _("No signature\n"));
00144 rc = 0;
00145 break;
00146 case RPMSIG_PGP262_1024:
00147 rpmMessage(RPMMESS_DEBUG, _("Old PGP signature\n"));
00148
00149 if (timedRead(fd, buf, 256) != 256)
00150 break;
00151 h = headerNew();
00152 headerAddEntry(h, RPMSIGTAG_PGP, RPM_BIN_TYPE, buf, 152);
00153 rc = 0;
00154 break;
00155 case RPMSIG_MD5:
00156 case RPMSIG_MD5_PGP:
00157 rpmError(RPMERR_BADSIGTYPE,
00158 _("Old (internal-only) signature! How did you get that!?\n"));
00159 break;
00160 case RPMSIG_HEADERSIG:
00161
00162 h = headerRead(fd, HEADER_MAGIC_YES);
00163 if (h == NULL)
00164 break;
00165 sigSize = headerSizeof(h, HEADER_MAGIC_YES);
00166
00167
00168 if (headerIsEntry(h, RPMTAG_HEADERIMAGE))
00169 sigSize -= (16 + 16);
00170
00171 pad = (8 - (sigSize % 8)) % 8;
00172 if (! headerGetEntry(h, RPMSIGTAG_SIZE, &type, (void **)&archSize, &count))
00173 break;
00174 nb = checkSize(fd, sigSize, pad, *archSize);
00175 if (!(nb == 0 || nb == -(16+16)))
00176 break;
00177 if (pad) {
00178 if (timedRead(fd, buf, pad) != pad)
00179 break;
00180 }
00181 rc = 0;
00182 break;
00183 default:
00184 break;
00185 }
00186
00187 if (rc == 0 && headerp)
00188 *headerp = h;
00189 else if (h)
00190 headerFree(h);
00191
00192 return rc;
00193 }
00194
00195 int rpmWriteSignature(FD_t fd, Header header)
00196 {
00197 int sigSize, pad;
00198 static byte buf[8] = "\000\000\000\000\000\000\000\000";
00199 int rc = 0;
00200
00201 rc = headerWrite(fd, header, HEADER_MAGIC_YES);
00202 if (rc)
00203 return rc;
00204
00205 sigSize = headerSizeof(header, HEADER_MAGIC_YES);
00206 pad = (8 - (sigSize % 8)) % 8;
00207 if (pad) {
00208 rpmMessage(RPMMESS_DEBUG, _("Signature size: %d\n"), sigSize);
00209 rpmMessage(RPMMESS_DEBUG, _("Signature pad : %d\n"), pad);
00210 if (Fwrite(buf, sizeof(buf[0]), pad, fd) != pad)
00211 rc = 1;
00212 }
00213 return rc;
00214 }
00215
00216 Header rpmNewSignature(void)
00217 {
00218 Header h = headerNew();
00219 return h;
00220 }
00221
00222 void rpmFreeSignature(Header h)
00223 {
00224 headerFree(h);
00225 }
00226
00227 static int makePGPSignature(const char *file, void **sig, int_32 *size,
00228 const char *passPhrase)
00229 {
00230 char sigfile[1024];
00231 int pid, status;
00232 int inpipe[2];
00233 struct stat st;
00234
00235 sprintf(sigfile, "%s.sig", file);
00236
00237 inpipe[0] = inpipe[1] = 0;
00238 pipe(inpipe);
00239
00240 if (!(pid = fork())) {
00241 const char *pgp_path = rpmExpand("%{_pgp_path}", NULL);
00242 const char *name = rpmExpand("+myname=\"%{_pgp_name}\"", NULL);
00243 const char *path;
00244 pgpVersion pgpVer;
00245
00246 close(STDIN_FILENO);
00247 dup2(inpipe[0], 3);
00248 close(inpipe[1]);
00249
00250 dosetenv("PGPPASSFD", "3", 1);
00251 if (pgp_path && *pgp_path != '%')
00252 dosetenv("PGPPATH", pgp_path, 1);
00253
00254
00255
00256 if ((path = rpmDetectPGPVersion(&pgpVer)) != NULL) {
00257 switch(pgpVer) {
00258 case PGP_2:
00259 execlp(path, "pgp", "+batchmode=on", "+verbose=0", "+armor=off",
00260 name, "-sb", file, sigfile, NULL);
00261 break;
00262 case PGP_5:
00263 execlp(path,"pgps", "+batchmode=on", "+verbose=0", "+armor=off",
00264 name, "-b", file, "-o", sigfile, NULL);
00265 break;
00266 case PGP_UNKNOWN:
00267 case PGP_NOTDETECTED:
00268 break;
00269 }
00270 }
00271 rpmError(RPMERR_EXEC, _("Couldn't exec pgp (%s)\n"), path);
00272 _exit(RPMERR_EXEC);
00273 }
00274
00275 close(inpipe[0]);
00276 (void)write(inpipe[1], passPhrase, strlen(passPhrase));
00277 (void)write(inpipe[1], "\n", 1);
00278 close(inpipe[1]);
00279
00280 (void)waitpid(pid, &status, 0);
00281 if (!WIFEXITED(status) || WEXITSTATUS(status)) {
00282 rpmError(RPMERR_SIGGEN, _("pgp failed\n"));
00283 return 1;
00284 }
00285
00286 if (stat(sigfile, &st)) {
00287
00288 unlink(sigfile);
00289 rpmError(RPMERR_SIGGEN, _("pgp failed to write signature\n"));
00290 return 1;
00291 }
00292
00293 *size = st.st_size;
00294 rpmMessage(RPMMESS_DEBUG, _("PGP sig size: %d\n"), *size);
00295 *sig = xmalloc(*size);
00296
00297 { FD_t fd;
00298 int rc;
00299 fd = Fopen(sigfile, "r.fdio");
00300 rc = timedRead(fd, *sig, *size);
00301 unlink(sigfile);
00302 Fclose(fd);
00303 if (rc != *size) {
00304 free(*sig);
00305 rpmError(RPMERR_SIGGEN, _("unable to read the signature\n"));
00306 return 1;
00307 }
00308 }
00309
00310 rpmMessage(RPMMESS_DEBUG, _("Got %d bytes of PGP sig\n"), *size);
00311
00312 return 0;
00313 }
00314
00315
00316
00317
00318
00319
00320 static int makeGPGSignature(const char *file, void **sig, int_32 *size,
00321 const char *passPhrase)
00322 {
00323 char sigfile[1024];
00324 int pid, status;
00325 int inpipe[2];
00326 FILE *fpipe;
00327 struct stat st;
00328
00329 sprintf(sigfile, "%s.sig", file);
00330
00331 inpipe[0] = inpipe[1] = 0;
00332 pipe(inpipe);
00333
00334 if (!(pid = fork())) {
00335 const char *gpg_path = rpmExpand("%{_gpg_path}", NULL);
00336 const char *name = rpmExpand("%{_gpg_name}", NULL);
00337
00338 close(STDIN_FILENO);
00339 dup2(inpipe[0], 3);
00340 close(inpipe[1]);
00341
00342 if (gpg_path && *gpg_path != '%')
00343 dosetenv("GNUPGHOME", gpg_path, 1);
00344 execlp("gpg", "gpg",
00345 "--batch", "--no-verbose", "--no-armor", "--passphrase-fd", "3",
00346 "-u", name, "-sbo", sigfile, file,
00347 NULL);
00348 rpmError(RPMERR_EXEC, _("Couldn't exec gpg\n"));
00349 _exit(RPMERR_EXEC);
00350 }
00351
00352 fpipe = fdopen(inpipe[1], "w");
00353 close(inpipe[0]);
00354 fprintf(fpipe, "%s\n", passPhrase);
00355 fclose(fpipe);
00356
00357 (void)waitpid(pid, &status, 0);
00358 if (!WIFEXITED(status) || WEXITSTATUS(status)) {
00359 rpmError(RPMERR_SIGGEN, _("gpg failed\n"));
00360 return 1;
00361 }
00362
00363 if (stat(sigfile, &st)) {
00364
00365 unlink(sigfile);
00366 rpmError(RPMERR_SIGGEN, _("gpg failed to write signature\n"));
00367 return 1;
00368 }
00369
00370 *size = st.st_size;
00371 rpmMessage(RPMMESS_DEBUG, _("GPG sig size: %d\n"), *size);
00372 *sig = xmalloc(*size);
00373
00374 { FD_t fd;
00375 int rc;
00376 fd = Fopen(sigfile, "r.fdio");
00377 rc = timedRead(fd, *sig, *size);
00378 unlink(sigfile);
00379 Fclose(fd);
00380 if (rc != *size) {
00381 free(*sig);
00382 rpmError(RPMERR_SIGGEN, _("unable to read the signature\n"));
00383 return 1;
00384 }
00385 }
00386
00387 rpmMessage(RPMMESS_DEBUG, _("Got %d bytes of GPG sig\n"), *size);
00388
00389 return 0;
00390 }
00391
00392 int rpmAddSignature(Header header, const char *file, int_32 sigTag, const char *passPhrase)
00393 {
00394 struct stat st;
00395 int_32 size;
00396 byte buf[16];
00397 void *sig;
00398 int ret = -1;
00399
00400 switch (sigTag) {
00401 case RPMSIGTAG_SIZE:
00402 stat(file, &st);
00403 size = st.st_size;
00404 ret = 0;
00405 headerAddEntry(header, RPMSIGTAG_SIZE, RPM_INT32_TYPE, &size, 1);
00406 break;
00407 case RPMSIGTAG_MD5:
00408 ret = mdbinfile(file, buf);
00409 if (ret == 0)
00410 headerAddEntry(header, sigTag, RPM_BIN_TYPE, buf, 16);
00411 break;
00412 case RPMSIGTAG_PGP5:
00413 case RPMSIGTAG_PGP:
00414 rpmMessage(RPMMESS_VERBOSE, _("Generating signature using PGP.\n"));
00415 ret = makePGPSignature(file, &sig, &size, passPhrase);
00416 if (ret == 0)
00417 headerAddEntry(header, sigTag, RPM_BIN_TYPE, sig, size);
00418 break;
00419 case RPMSIGTAG_GPG:
00420 rpmMessage(RPMMESS_VERBOSE, _("Generating signature using GPG.\n"));
00421 ret = makeGPGSignature(file, &sig, &size, passPhrase);
00422 if (ret == 0)
00423 headerAddEntry(header, sigTag, RPM_BIN_TYPE, sig, size);
00424 break;
00425 }
00426
00427 return ret;
00428 }
00429
00430 static rpmVerifySignatureReturn
00431 verifySizeSignature(const char *datafile, int_32 size, char *result)
00432 {
00433 struct stat st;
00434
00435 stat(datafile, &st);
00436 if (size != st.st_size) {
00437 sprintf(result, "Header+Archive size mismatch.\n"
00438 "Expected %d, saw %d.\n",
00439 size, (int)st.st_size);
00440 return RPMSIG_BAD;
00441 }
00442
00443 sprintf(result, "Header+Archive size OK: %d bytes\n", size);
00444 return RPMSIG_OK;
00445 }
00446
00447 #define X(_x) (unsigned)((_x) & 0xff)
00448
00449 static rpmVerifySignatureReturn
00450 verifyMD5Signature(const char *datafile, const byte *sig,
00451 char *result, md5func fn)
00452 {
00453 byte md5sum[16];
00454
00455 fn(datafile, md5sum);
00456 if (memcmp(md5sum, sig, 16)) {
00457 sprintf(result, "MD5 sum mismatch\n"
00458 "Expected: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
00459 "%02x%02x%02x%02x%02x\n"
00460 "Saw : %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
00461 "%02x%02x%02x%02x%02x\n",
00462 X(sig[0]), X(sig[1]), X(sig[2]), X(sig[3]),
00463 X(sig[4]), X(sig[5]), X(sig[6]), X(sig[7]),
00464 X(sig[8]), X(sig[9]), X(sig[10]), X(sig[11]),
00465 X(sig[12]), X(sig[13]), X(sig[14]), X(sig[15]),
00466 X(md5sum[0]), X(md5sum[1]), X(md5sum[2]), X(md5sum[3]),
00467 X(md5sum[4]), X(md5sum[5]), X(md5sum[6]), X(md5sum[7]),
00468 X(md5sum[8]), X(md5sum[9]), X(md5sum[10]), X(md5sum[11]),
00469 X(md5sum[12]), X(md5sum[13]), X(md5sum[14]), X(md5sum[15]) );
00470 return RPMSIG_BAD;
00471 }
00472
00473 sprintf(result, "MD5 sum OK: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
00474 "%02x%02x%02x%02x%02x\n",
00475 X(md5sum[0]), X(md5sum[1]), X(md5sum[2]), X(md5sum[3]),
00476 X(md5sum[4]), X(md5sum[5]), X(md5sum[6]), X(md5sum[7]),
00477 X(md5sum[8]), X(md5sum[9]), X(md5sum[10]), X(md5sum[11]),
00478 X(md5sum[12]), X(md5sum[13]), X(md5sum[14]), X(md5sum[15]) );
00479
00480 return RPMSIG_OK;
00481 }
00482
00483 static rpmVerifySignatureReturn
00484 verifyPGPSignature(const char *datafile, const void * sig, int count, char *result)
00485 {
00486 int pid, status, outpipe[2];
00487 FD_t sfd;
00488 char *sigfile;
00489 byte buf[BUFSIZ];
00490 FILE *file;
00491 int res = RPMSIG_OK;
00492 const char *path;
00493 pgpVersion pgpVer;
00494
00495
00496 if ((path = rpmDetectPGPVersion(&pgpVer)) == NULL) {
00497 errno = ENOENT;
00498 rpmError(RPMERR_EXEC,
00499 _("Could not run pgp. Use --nopgp to skip PGP checks.\n"));
00500 _exit(RPMERR_EXEC);
00501 }
00502
00503
00504
00505
00506
00507 if (pgpVer == PGP_5)
00508 res = RPMSIG_BAD;
00509
00510
00511 { const char *tmppath = rpmGetPath("%{_tmppath}", NULL);
00512 sigfile = tempnam(tmppath, "rpmsig");
00513 free((void *)tmppath);
00514 }
00515 sfd = Fopen(sigfile, "w.fdio");
00516 (void)Fwrite(sig, sizeof(char), count, sfd);
00517 Fclose(sfd);
00518
00519
00520 outpipe[0] = outpipe[1] = 0;
00521 pipe(outpipe);
00522
00523 if (!(pid = fork())) {
00524 const char *pgp_path = rpmExpand("%{_pgp_path}", NULL);
00525
00526 close(outpipe[0]);
00527 close(STDOUT_FILENO);
00528 dup2(outpipe[1], STDOUT_FILENO);
00529
00530 if (pgp_path && *pgp_path != '%')
00531 dosetenv("PGPPATH", pgp_path, 1);
00532
00533 switch (pgpVer) {
00534 case PGP_5:
00535
00536
00537
00538 { int save_stderr = dup(2);
00539 dup2(1, 2);
00540 execlp(path, "pgpv", "+batchmode=on", "+verbose=0",
00541
00542 "+OutputInformationFD=1",
00543
00544 "+OutputWarningFD=1",
00545 sigfile, "-o", datafile, NULL);
00546
00547 dup2(save_stderr, 2);
00548 close(save_stderr);
00549 } break;
00550 case PGP_2:
00551 execlp(path, "pgp", "+batchmode=on", "+verbose=0",
00552 sigfile, datafile, NULL);
00553 break;
00554 case PGP_UNKNOWN:
00555 case PGP_NOTDETECTED:
00556 break;
00557 }
00558
00559 rpmError(RPMERR_EXEC,
00560 _("Could not run pgp. Use --nopgp to skip PGP checks.\n"));
00561 _exit(RPMERR_EXEC);
00562 }
00563
00564 close(outpipe[1]);
00565 file = fdopen(outpipe[0], "r");
00566 result[0] = '\0';
00567 while (fgets(buf, 1024, file)) {
00568 if (strncmp("File '", buf, 6) &&
00569 strncmp("Text is assu", buf, 12) &&
00570 strncmp("This signature applies to another message", buf, 41) &&
00571 buf[0] != '\n') {
00572 strcat(result, buf);
00573 }
00574 if (!strncmp("WARNING: Can't find the right public key", buf, 40))
00575 res = RPMSIG_NOKEY;
00576 else if (!strncmp("Signature by unknown keyid:", buf, 27))
00577 res = RPMSIG_NOKEY;
00578 else if (!strncmp("WARNING: The signing key is not trusted", buf, 39))
00579 res = RPMSIG_NOTTRUSTED;
00580 else if (!strncmp("Good signature", buf, 14))
00581 res = RPMSIG_OK;
00582 }
00583 fclose(file);
00584
00585 (void)waitpid(pid, &status, 0);
00586 unlink(sigfile);
00587 if (!res && (!WIFEXITED(status) || WEXITSTATUS(status))) {
00588 res = RPMSIG_BAD;
00589 }
00590
00591 return res;
00592 }
00593
00594 static rpmVerifySignatureReturn
00595 verifyGPGSignature(const char *datafile, const void * sig, int count, char *result)
00596 {
00597 int pid, status, outpipe[2];
00598 FD_t sfd;
00599 char *sigfile;
00600 byte buf[BUFSIZ];
00601 FILE *file;
00602 int res = RPMSIG_OK;
00603
00604
00605 { const char *tmppath = rpmGetPath("%{_tmppath}", NULL);
00606 sigfile = tempnam(tmppath, "rpmsig");
00607 free((void *)tmppath);
00608 }
00609 sfd = Fopen(sigfile, "w.fdio");
00610 (void)Fwrite(sig, sizeof(char), count, sfd);
00611 Fclose(sfd);
00612
00613
00614 outpipe[0] = outpipe[1] = 0;
00615 pipe(outpipe);
00616
00617 if (!(pid = fork())) {
00618 const char *gpg_path = rpmExpand("%{_gpg_path}", NULL);
00619
00620 close(outpipe[0]);
00621
00622 dup2(outpipe[1], STDERR_FILENO);
00623
00624 if (gpg_path && *gpg_path != '%')
00625 dosetenv("GNUPGHOME", gpg_path, 1);
00626
00627 execlp("gpg", "gpg",
00628 "--batch", "--no-verbose",
00629 "--verify", sigfile, datafile,
00630 NULL);
00631 rpmError(RPMERR_EXEC,
00632 _("Could not run gpg. Use --nogpg to skip GPG checks.\n"));
00633 _exit(RPMERR_EXEC);
00634 }
00635
00636 close(outpipe[1]);
00637 file = fdopen(outpipe[0], "r");
00638 result[0] = '\0';
00639 while (fgets(buf, 1024, file)) {
00640 strcat(result, buf);
00641 if (!xstrncasecmp("gpg: Can't check signature: Public key not found", buf, 48)) {
00642 res = RPMSIG_NOKEY;
00643 }
00644 }
00645 fclose(file);
00646
00647 (void)waitpid(pid, &status, 0);
00648 unlink(sigfile);
00649 if (!res && (!WIFEXITED(status) || WEXITSTATUS(status))) {
00650 res = RPMSIG_BAD;
00651 }
00652
00653 return res;
00654 }
00655
00656 static int checkPassPhrase(const char *passPhrase, const int sigTag)
00657 {
00658 int passPhrasePipe[2];
00659 int pid, status;
00660 int fd;
00661
00662 passPhrasePipe[0] = passPhrasePipe[1] = 0;
00663 pipe(passPhrasePipe);
00664 if (!(pid = fork())) {
00665 close(STDIN_FILENO);
00666 close(STDOUT_FILENO);
00667 close(passPhrasePipe[1]);
00668 if (! rpmIsVerbose()) {
00669 close(STDERR_FILENO);
00670 }
00671 if ((fd = open("/dev/null", O_RDONLY)) != STDIN_FILENO) {
00672 dup2(fd, STDIN_FILENO);
00673 close(fd);
00674 }
00675 if ((fd = open("/dev/null", O_WRONLY)) != STDOUT_FILENO) {
00676 dup2(fd, STDOUT_FILENO);
00677 close(fd);
00678 }
00679 dup2(passPhrasePipe[0], 3);
00680
00681 switch (sigTag) {
00682 case RPMSIGTAG_GPG:
00683 { const char *gpg_path = rpmExpand("%{_gpg_path}", NULL);
00684 const char *name = rpmExpand("%{_gpg_name}", NULL);
00685 if (gpg_path && *gpg_path != '%')
00686 dosetenv("GNUPGHOME", gpg_path, 1);
00687 execlp("gpg", "gpg",
00688 "--batch", "--no-verbose", "--passphrase-fd", "3",
00689 "-u", name, "-so", "-",
00690 NULL);
00691 rpmError(RPMERR_EXEC, _("Couldn't exec gpg\n"));
00692 _exit(RPMERR_EXEC);
00693 } break;
00694 case RPMSIGTAG_PGP5:
00695 case RPMSIGTAG_PGP:
00696 { const char *pgp_path = rpmExpand("%{_pgp_path}", NULL);
00697 const char *name = rpmExpand("+myname=\"%{_pgp_name}\"", NULL);
00698 const char *path;
00699 pgpVersion pgpVer;
00700
00701 dosetenv("PGPPASSFD", "3", 1);
00702 if (pgp_path && *pgp_path != '%')
00703 dosetenv("PGPPATH", pgp_path, 1);
00704
00705 if ((path = rpmDetectPGPVersion(&pgpVer)) != NULL) {
00706 switch(pgpVer) {
00707 case PGP_2:
00708 execlp(path, "pgp", "+batchmode=on", "+verbose=0",
00709 name, "-sf", NULL);
00710 break;
00711 case PGP_5:
00712 execlp(path,"pgps", "+batchmode=on", "+verbose=0",
00713 name, "-f", NULL);
00714 break;
00715 case PGP_UNKNOWN:
00716 case PGP_NOTDETECTED:
00717 break;
00718 }
00719 }
00720 rpmError(RPMERR_EXEC, _("Couldn't exec pgp\n"));
00721 _exit(RPMERR_EXEC);
00722 } break;
00723 default:
00724 rpmError(RPMERR_SIGGEN, _("Invalid %%_signature spec in macro file\n"));
00725 _exit(RPMERR_SIGGEN);
00726 break;
00727 }
00728 }
00729
00730 close(passPhrasePipe[0]);
00731 (void)write(passPhrasePipe[1], passPhrase, strlen(passPhrase));
00732 (void)write(passPhrasePipe[1], "\n", 1);
00733 close(passPhrasePipe[1]);
00734
00735 (void)waitpid(pid, &status, 0);
00736 if (!WIFEXITED(status) || WEXITSTATUS(status)) {
00737 return 1;
00738 }
00739
00740
00741 return 0;
00742 }
00743
00744 char *rpmGetPassPhrase(const char *prompt, const int sigTag)
00745 {
00746 char *pass;
00747 int aok;
00748
00749 switch (sigTag) {
00750 case RPMSIGTAG_GPG:
00751 { const char *name = rpmExpand("%{_gpg_name}", NULL);
00752 aok = (name && *name != '%');
00753 free((void *)name);
00754 }
00755 if (!aok) {
00756 rpmError(RPMERR_SIGGEN,
00757 _("You must set \"%%_gpg_name\" in your macro file\n"));
00758 return NULL;
00759 }
00760 break;
00761 case RPMSIGTAG_PGP5:
00762 case RPMSIGTAG_PGP:
00763 { const char *name = rpmExpand("%{_pgp_name}", NULL);
00764 aok = (name && *name != '%');
00765 free((void *)name);
00766 }
00767 if (!aok) {
00768 rpmError(RPMERR_SIGGEN,
00769 _("You must set \"%%_pgp_name\" in your macro file\n"));
00770 return NULL;
00771 }
00772 break;
00773 default:
00774
00775
00776
00777 rpmError(RPMERR_SIGGEN, _("Invalid %%_signature spec in macro file\n"));
00778 return NULL;
00779 break;
00780 }
00781
00782 pass = getpass( (prompt ? prompt : "") ) ;
00783
00784 if (checkPassPhrase(pass, sigTag))
00785 return NULL;
00786
00787 return pass;
00788 }
00789
00790 rpmVerifySignatureReturn
00791 rpmVerifySignature(const char *file, int_32 sigTag, const void * sig, int count,
00792 char *result)
00793 {
00794 switch (sigTag) {
00795 case RPMSIGTAG_SIZE:
00796 return verifySizeSignature(file, *(int_32 *)sig, result);
00797 break;
00798 case RPMSIGTAG_MD5:
00799 return verifyMD5Signature(file, sig, result, mdbinfile);
00800 break;
00801 case RPMSIGTAG_LEMD5_1:
00802 case RPMSIGTAG_LEMD5_2:
00803 return verifyMD5Signature(file, sig, result, mdbinfileBroken);
00804 break;
00805 case RPMSIGTAG_PGP5:
00806 case RPMSIGTAG_PGP:
00807 return verifyPGPSignature(file, sig, count, result);
00808 break;
00809 case RPMSIGTAG_GPG:
00810 return verifyGPGSignature(file, sig, count, result);
00811 break;
00812 default:
00813 sprintf(result, "Do not know how to verify sig type %d\n", sigTag);
00814 return RPMSIG_UNKNOWN;
00815 }
00816
00817 return RPMSIG_OK;
00818 }