RPM Package Manager, CVS Repository
http://rpm5.org/cvs/
____________________________________________________________________________
Server: rpm5.org Name: Jeff Johnson
Root: /v/rpm/cvs Email: jbj@rpm5.org
Module: rpm Date: 01-Oct-2007 00:38:31
Branch: HEAD Handle: 2007093023382703
Added files:
rpm/rpmdb signature.c signature.h
Modified files:
rpm CHANGES
rpm/build build.c pack.c
rpm/lib Makefile.am librpm.vers misc.c misc.h psm.c
rpmchecksig.c rpmlib.h rpmts.c
rpm/python rpmts-py.c
rpm/rpmdb Makefile.am librpmdb.vers pkgio.c rpmdb.c
Removed files:
rpm/lib signature.c signature.h
Log:
- insure rpmlib -> rpmdb forward linkage only.
Summary:
Revision Changes Path
1.1650 +1 -0 rpm/CHANGES
2.116 +2 -1 rpm/build/build.c
2.229 +2 -1 rpm/build/pack.c
2.166 +2 -2 rpm/lib/Makefile.am
1.20 +0 -4 rpm/lib/librpm.vers
2.144 +0 -104 rpm/lib/misc.c
2.67 +0 -21 rpm/lib/misc.h
2.233 +3 -3 rpm/lib/psm.c
1.148 +2 -3 rpm/lib/rpmchecksig.c
2.439 +0 -12 rpm/lib/rpmlib.h
2.104 +0 -11 rpm/lib/rpmts.c
2.193 +0 -1239 rpm/lib/signature.c
2.48 +0 -52 rpm/lib/signature.h
1.71 +1 -0 rpm/python/rpmts-py.c
1.81 +2 -2 rpm/rpmdb/Makefile.am
1.19 +5 -0 rpm/rpmdb/librpmdb.vers
1.10 +38 -18 rpm/rpmdb/pkgio.c
1.163 +10 -0 rpm/rpmdb/rpmdb.c
1.1 +1344 -0 rpm/rpmdb/signature.c
1.1 +85 -0 rpm/rpmdb/signature.h
____________________________________________________________________________
patch -p0 <<'@@ .'
Index: rpm/CHANGES
============================================================================
$ cvs diff -u -r1.1649 -r1.1650 CHANGES
--- rpm/CHANGES 29 Sep 2007 19:29:00 -0000 1.1649
+++ rpm/CHANGES 30 Sep 2007 22:38:27 -0000 1.1650
@@ -1,4 +1,5 @@
4.5 -> 5.0:
+ - jbj: insure rpmlib -> rpmdb forward linkage only.
- jbj: eliminate (*hdrchk) vector everywhere, use headerCheck() instead.
- jbj: add metadata header stubs to pkgio.c.
- jbj: move rpmtsFindPubkey() and rpmtsOp() to rpmdb for forward linkage.
@@ .
patch -p0 <<'@@ .'
Index: rpm/build/build.c
============================================================================
$ cvs diff -u -r2.115 -r2.116 build.c
--- rpm/build/build.c 17 Aug 2007 00:13:56 -0000 2.115
+++ rpm/build/build.c 30 Sep 2007 22:38:28 -0000 2.116
@@ -7,6 +7,7 @@
#include <rpmio_internal.h>
#include <rpmbuild.h>
+#include "signature.h" /* XXX rpmTempFile */
#include "debug.h"
@@ -145,7 +146,7 @@
goto exit;
}
- if (makeTempFile(rootURL, &scriptName, &fd) || fd == NULL || Ferror(fd)) {
+ if (rpmTempFile(rootURL, &scriptName, &fd) || fd == NULL || Ferror(fd)) {
rpmError(RPMERR_SCRIPT, _("Unable to open temp file.\n"));
rc = RPMERR_SCRIPT;
goto exit;
@@ .
patch -p0 <<'@@ .'
Index: rpm/build/pack.c
============================================================================
$ cvs diff -u -r2.228 -r2.229 pack.c
--- rpm/build/pack.c 29 Sep 2007 18:18:57 -0000 2.228
+++ rpm/build/pack.c 30 Sep 2007 22:38:28 -0000 2.229
@@ -8,6 +8,7 @@
#include <rpmio_internal.h>
#define _RPMEVR_INTERNAL /* XXX RPMSENSE_ANY */
#include <rpmbuild.h>
+#include "signature.h" /* XXX rpmTempFile */
#include "rpmps.h"
@@ -618,7 +619,7 @@
* archive (after compression) can be added to the header.
*/
sigtarget = NULL;
- if (makeTempFile(NULL, &sigtarget, &fd)) {
+ if (rpmTempFile(NULL, &sigtarget, &fd)) {
rc = RPMERR_CREATE;
rpmError(RPMERR_CREATE, _("Unable to open temp file.\n"));
goto exit;
@@ .
patch -p0 <<'@@ .'
Index: rpm/lib/Makefile.am
============================================================================
$ cvs diff -u -r2.165 -r2.166 Makefile.am
--- rpm/lib/Makefile.am 8 Sep 2007 16:17:33 -0000 2.165
+++ rpm/lib/Makefile.am 30 Sep 2007 22:38:28 -0000 2.166
@@ -27,7 +27,7 @@
rpmal.h rpmdpkg.h rpmds.h rpmevr.h rpmfc.h rpmfi.h rpmgi.h \
rpmns.h rpmps.h rpmsx.h rpmte.h rpmts.h stringbuf.h
noinst_HEADERS = \
- cpio.h fsm.h manifest.h psm.h rpmlock.h signature.h tar.h
+ cpio.h fsm.h manifest.h psm.h rpmlock.h tar.h
usrlibdir = $(libdir)
usrlib_LTLIBRARIES = librpm.la
@@ -38,7 +38,7 @@
rpmal.c rpmchecksig.c rpmdpkg.c rpmds.c rpmevr.c rpmfc.c \
rpmfi.c rpmgi.c rpminstall.c rpmrollback.c \
rpmlock.c rpmns.c rpmps.c rpmrc.c rpmsx.c rpmte.c rpmts.c \
- signature.c stringbuf.c transaction.c \
+ stringbuf.c transaction.c \
verify.c tar.c
librpm_la_LDFLAGS = -release $(LT_CURRENT).$(LT_REVISION)
if HAVE_LD_VERSION_SCRIPT
@@ .
patch -p0 <<'@@ .'
Index: rpm/lib/librpm.vers
============================================================================
$ cvs diff -u -r1.19 -r1.20 librpm.vers
--- rpm/lib/librpm.vers 29 Sep 2007 16:23:39 -0000 1.19
+++ rpm/lib/librpm.vers 30 Sep 2007 22:38:28 -0000 1.20
@@ -49,7 +49,6 @@
_print_pkts;
_psm_debug;
_psm_threads;
- rpmAddSignature;
rpmalAdd;
rpmalAddProvides;
rpmalAllFileSatisfiesDepend;
@@ -60,7 +59,6 @@
rpmalFree;
rpmalMakeIndex;
rpmalSatisfiesDepend;
- rpmCheckPassPhrase;
rpmcliAllPoptTable;
rpmcliArgIter;
rpmcliConfigured;
@@ -346,7 +344,6 @@
rpmtsFlags;
rpmtsFree;
rpmtsFreeLock;
- rpmtsGetRdb;
rpmtsGetTid;
rpmtsGetType;
rpmtsGoal;
@@ -399,7 +396,6 @@
rpmvercmp;
rpmVerifyFile;
rpmVerifyPoptTable;
- rpmVerifySignature;
rpmVerifySignatures;
RPMVERSION;
rpmVersionCompare;
@@ .
patch -p0 <<'@@ .'
Index: rpm/lib/misc.c
============================================================================
$ cvs diff -u -r2.143 -r2.144 misc.c
--- rpm/lib/misc.c 30 Sep 2007 20:38:25 -0000 2.143
+++ rpm/lib/misc.c 30 Sep 2007 22:38:28 -0000 2.144
@@ -113,110 +113,6 @@
return putenv(a);
}
-int makeTempFile(const char * prefix, const char ** fnptr, void * fdptr)
-{
- const char * tpmacro = "%{?_tmppath}%{!?_tmppath:/var/tmp/}";
- const char * tempfn = NULL;
- const char * tfn = NULL;
- static int _initialized = 0;
- int temput;
- FD_t fd = NULL;
- int ran;
-
- if (!prefix) prefix = "";
-
- /* Create the temp directory if it doesn't already exist. */
- if (!_initialized) {
- _initialized = 1;
- tempfn = rpmGenPath(prefix, tpmacro, NULL);
- if (rpmioMkpath(tempfn, 0755, (uid_t) -1, (gid_t) -1))
- goto errxit;
- }
-
- /* XXX should probably use mkstemp here */
- srand(time(NULL));
- ran = rand() % 100000;
-
- /* maybe this should use link/stat? */
-
- do {
- char tfnbuf[64];
-#ifndef NOTYET
- sprintf(tfnbuf, "rpm-tmp.%d", ran++);
- tempfn = _free(tempfn);
- tempfn = rpmGenPath(prefix, tpmacro, tfnbuf);
-#else
- strcpy(tfnbuf, "rpm-tmp.XXXXXX");
- tempfn = _free(tempfn);
- tempfn = rpmGenPath(prefix, tpmacro, mktemp(tfnbuf));
-#endif
-
- temput = urlPath(tempfn, &tfn);
- if (*tfn == '\0') goto errxit;
-
- switch (temput) {
- case URL_IS_DASH:
- case URL_IS_HKP:
- goto errxit;
- /*@notreached@*/ /*@switchbreak@*/ break;
- case URL_IS_HTTPS:
- case URL_IS_HTTP:
- case URL_IS_FTP:
- default:
- /*@switchbreak@*/ break;
- }
-
- fd = Fopen(tempfn, "w+x.fdio");
- /* XXX FIXME: errno may not be correct for ufdio */
- } while ((fd == NULL || Ferror(fd)) && errno == EEXIST);
-
- if (fd == NULL || Ferror(fd))
- goto errxit;
-
- switch(temput) {
- case URL_IS_PATH:
- case URL_IS_UNKNOWN:
- { struct stat sb, sb2;
- if (!stat(tfn, &sb) && S_ISLNK(sb.st_mode)) {
- rpmError(RPMERR_SCRIPT, _("error creating temporary file %s\n"), tfn);
- goto errxit;
- }
-
- if (sb.st_nlink != 1) {
- rpmError(RPMERR_SCRIPT, _("error creating temporary file %s\n"), tfn);
- goto errxit;
- }
-
- if (fstat(Fileno(fd), &sb2) == 0) {
- if (sb2.st_ino != sb.st_ino || sb2.st_dev != sb.st_dev) {
- rpmError(RPMERR_SCRIPT, _("error creating temporary file %s\n"), tfn);
- goto errxit;
- }
- }
- } break;
- default:
- break;
- }
-
- if (fnptr)
- *fnptr = tempfn;
- else
- tempfn = _free(tempfn);
- if (fdptr)
- *(FD_t *)fdptr = fd;
-
- return 0;
-
-errxit:
- tempfn = _free(tempfn);
- if (fnptr)
- *fnptr = NULL;
- /*@-usereleased@*/
- if (fd != NULL) (void) Fclose(fd);
- /*@=usereleased@*/
- return 1;
-}
-
char * currentDirectory(void)
{
int currDirLen = 0;
@@ .
patch -p0 <<'@@ .'
Index: rpm/lib/misc.h
============================================================================
$ cvs diff -u -r2.66 -r2.67 misc.h
--- rpm/lib/misc.h 16 Jul 2007 01:32:28 -0000 2.66
+++ rpm/lib/misc.h 30 Sep 2007 22:38:28 -0000 2.67
@@ -79,27 +79,6 @@
/*@modifies *environ @*/;
/**
- * Return file handle for a temporaray file.
- * A unique temporaray file path will be generated using
- * rpmGenPath(prefix, "%{_tmppath}/", "rpm-tmp.XXXXX")
- * where "XXXXXX" is filled in using rand(3). The file is opened, and
- * the link count and (dev,ino) location are verified after opening.
- * The file name and the open file handle are returned.
- *
- * @param prefix leading part of temp file path
- * @retval *fnptr temp file name (or NULL)
- * @retval *fdptr temp file handle
- * @return 0 on success
- */
-int makeTempFile(/*@null@*/ const char * prefix,
- /*@null@*/ /*@out@*/ const char ** fnptr,
- /*@out@*/ void * fdptr)
- /*@globals rpmGlobalMacroContext, h_errno,
- fileSystem, internalState @*/
- /*@modifies *fnptr, *fdptr, rpmGlobalMacroContext,
- fileSystem, internalState @*/;
-
-/**
* Return (malloc'd) current working directory.
* @return current working directory (malloc'ed)
*/
@@ .
patch -p0 <<'@@ .'
Index: rpm/lib/psm.c
============================================================================
$ cvs diff -u -r2.232 -r2.233 psm.c
--- rpm/lib/psm.c 30 Sep 2007 20:38:25 -0000 2.232
+++ rpm/lib/psm.c 30 Sep 2007 22:38:28 -0000 2.233
@@ -28,9 +28,9 @@
#include "rpmts.h"
#include <pkgio.h>
-#include "signature.h" /* signature constants */
-#include "misc.h" /* XXX stripTrailingChar() */
+#include "misc.h" /* XXX rpmMkdirPath */
#include "rpmdb.h" /* XXX for db_chrootDone */
+#include "signature.h" /* signature constants */
#include "debug.h"
#define _PSM_DEBUG 0
@@ -701,7 +701,7 @@
const char * rootDir = rpmtsRootDir(ts);
FD_t fd;
- if (makeTempFile((!rpmtsChrootDone(ts) ? rootDir : "/"), &fn, &fd))
+ if (rpmTempFile((!rpmtsChrootDone(ts) ? rootDir : "/"), &fn, &fd))
goto exit;
if (rpmIsDebug() &&
@@ .
patch -p0 <<'@@ .'
Index: rpm/lib/rpmchecksig.c
============================================================================
$ cvs diff -u -r1.147 -r1.148 rpmchecksig.c
--- rpm/lib/rpmchecksig.c 30 Sep 2007 20:38:25 -0000 1.147
+++ rpm/lib/rpmchecksig.c 30 Sep 2007 22:38:28 -0000 1.148
@@ -17,7 +17,6 @@
#include <pkgio.h>
#include "signature.h"
-#include "misc.h" /* XXX for makeTempFile() */
#include "debug.h"
/*@access FD_t @*/ /* XXX stealing digests */
@@ -68,8 +67,8 @@
/* open a temp file */
if (*fdp == NULL && (fnp == NULL || *fnp == NULL)) {
fn = NULL;
- if (makeTempFile(NULL, (fnp ? &fn : NULL), &fd)) {
- rpmError(RPMERR_MAKETEMP, _("makeTempFile failed\n"));
+ if (rpmTempFile(NULL, (fnp ? &fn : NULL), &fd)) {
+ rpmError(RPMERR_MAKETEMP, _("rpmTempFile failed\n"));
return 1;
}
if (fnp != NULL)
@@ .
patch -p0 <<'@@ .'
Index: rpm/lib/rpmlib.h
============================================================================
$ cvs diff -u -r2.438 -r2.439 rpmlib.h
--- rpm/lib/rpmlib.h 30 Sep 2007 20:38:25 -0000 2.438
+++ rpm/lib/rpmlib.h 30 Sep 2007 22:38:28 -0000 2.439
@@ -938,18 +938,6 @@
RPMSIGTAG_RSA = RPMTAG_RSAHEADER /*!< internal RSA header signature. */
};
-/** \ingroup signature
- * Verify a signature from a package.
- *
- * @param _dig container
- * @retval result detailed text result of signature verification
- * @return result of signature verification
- */
-rpmRC rpmVerifySignature(void * _dig, /*@out@*/ char * result)
- /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
- /*@modifies _dig, *result, rpmGlobalMacroContext,
- fileSystem, internalState @*/;
-
/*@}*/
#ifdef __cplusplus
@@ .
patch -p0 <<'@@ .'
Index: rpm/lib/rpmts.c
============================================================================
$ cvs diff -u -r2.103 -r2.104 rpmts.c
--- rpm/lib/rpmts.c 30 Sep 2007 20:38:26 -0000 2.103
+++ rpm/lib/rpmts.c 30 Sep 2007 22:38:28 -0000 2.104
@@ -881,17 +881,6 @@
return otid;
}
-rpmdb rpmtsGetRdb(rpmts ts)
-{
- rpmdb rdb = NULL;
- if (ts != NULL) {
- rdb = ts->rdb;
- }
-/*@-compdef -refcounttrans -usereleased @*/
- return rdb;
-/*@=compdef =refcounttrans =usereleased @*/
-}
-
rpmPRCO rpmtsPRCO(rpmts ts)
{
/*@-compdef -retexpose -usereleased @*/
@@ .
rm -f rpm/lib/signature.c <<'@@ .'
Index: rpm/lib/signature.c
============================================================================
[NO CHANGE SUMMARY BECAUSE FILE AS A WHOLE IS JUST REMOVED]
@@ .
rm -f rpm/lib/signature.h <<'@@ .'
Index: rpm/lib/signature.h
============================================================================
[NO CHANGE SUMMARY BECAUSE FILE AS A WHOLE IS JUST REMOVED]
@@ .
patch -p0 <<'@@ .'
Index: rpm/python/rpmts-py.c
============================================================================
$ cvs diff -u -r1.70 -r1.71 rpmts-py.c
--- rpm/python/rpmts-py.c 21 Aug 2007 03:41:52 -0000 1.70
+++ rpm/python/rpmts-py.c 30 Sep 2007 22:38:30 -0000 1.71
@@ -10,6 +10,7 @@
#include <rpmcli.h>
#include <rpmpgp.h>
#include <rpmdb.h>
+#include <pkgio.h> /* XXX headerCheck() */
#include <rpmbuild.h>
#include "header-py.h"
@@ .
patch -p0 <<'@@ .'
Index: rpm/rpmdb/Makefile.am
============================================================================
$ cvs diff -u -r1.80 -r1.81 Makefile.am
--- rpm/rpmdb/Makefile.am 30 Sep 2007 17:29:05 -0000 1.80
+++ rpm/rpmdb/Makefile.am 30 Sep 2007 22:38:30 -0000 1.81
@@ -26,7 +26,7 @@
tjfn_LDADD = librpmdb.la
pkgincdir = $(pkgincludedir)$(WITH_PATH_VERSIONED_SUFFIX)
-pkginc_HEADERS = header.h hdrinline.h pkgio.h rpmdb.h
+pkginc_HEADERS = header.h hdrinline.h pkgio.h rpmdb.h signature.h
noinst_HEADERS = fprint.h header_internal.h legacy.h
pkglibdir = @USRLIBRPM@
@@ -42,7 +42,7 @@
dbconfig.c fprint.c \
hdrfmt.c hdrNVR.c header.c header_internal.c legacy.c merge.c \
pkgio.c poptDB.c rpmdb.c \
- tagname.c tagtbl.c
+ signature.c tagname.c tagtbl.c
librpmdb_la_LDFLAGS = -release $(LT_CURRENT).$(LT_REVISION)
if HAVE_LD_VERSION_SCRIPT
librpmdb_la_LDFLAGS += -Wl,--version-script=$(srcdir)/librpmdb.vers
@@ .
patch -p0 <<'@@ .'
Index: rpm/rpmdb/librpmdb.vers
============================================================================
$ cvs diff -u -r1.18 -r1.19 librpmdb.vers
--- rpm/rpmdb/librpmdb.vers 29 Sep 2007 17:06:25 -0000 1.18
+++ rpm/rpmdb/librpmdb.vers 30 Sep 2007 22:38:30 -0000 1.19
@@ -45,6 +45,8 @@
_newmagic;
prDbiOpenFlags;
rdbOptions;
+ rpmAddSignature;
+ rpmCheckPassPhrase;
rpmDatabasePoptTable;
rpmdbAdd;
rpmdbAppendIterator;
@@ -85,12 +87,15 @@
rpmTagTable;
rpmTagTableSize;
rpmTags;
+ rpmTempFile;
rpmtsCleanDig;
rpmtsDig;
rpmtsFindPubkey;
+ rpmtsGetRdb;
rpmtsOp;
rpmtsPubkey;
rpmtsSetSig;
+ rpmVerifySignature;
sqlitevec;
XrpmdbLink;
XrpmdbUnlink;
@@ .
patch -p0 <<'@@ .'
Index: rpm/rpmdb/pkgio.c
============================================================================
$ cvs diff -u -r1.9 -r1.10 pkgio.c
--- rpm/rpmdb/pkgio.c 30 Sep 2007 17:29:05 -0000 1.9
+++ rpm/rpmdb/pkgio.c 30 Sep 2007 22:38:30 -0000 1.10
@@ -26,6 +26,7 @@
#include "header_internal.h"
#include <pkgio.h>
+#include "signature.h"
#include "debug.h"
/*@access rpmts @*/
@@ -59,6 +60,17 @@
/*@=onlytrans@*/
}
+rpmdb rpmtsGetRdb(rpmts ts)
+{
+ rpmdb rdb = NULL;
+ if (ts != NULL) {
+ rdb = ts->rdb;
+ }
+/*@-compdef -refcounttrans -usereleased @*/
+ return rdb;
+/*@=compdef =refcounttrans =usereleased @*/
+}
+
rpmRC rpmtsFindPubkey(rpmts ts, void * _dig)
{
pgpDig dig = (_dig ? _dig : rpmtsDig(ts));
@@ -72,8 +84,16 @@
#endif
int xx;
+#ifdef DYING
if (sig == NULL || dig == NULL || sigp == NULL || pubp == NULL)
goto exit;
+#else
+assert(sig != NULL);
+assert(dig != NULL);
+assert(sigp != NULL);
+assert(pubp != NULL);
+assert(rpmtsDig(ts) == dig);
+#endif
#if 0
fprintf(stderr, "==> find sig id %08x %08x ts pubkey id %08x %08x\n",
@@ -119,7 +139,7 @@
ts->pkpkt = _free(ts->pkpkt);
ts->pkpktlen = 0;
}
- }
+ }
/*@=moduncon@*/
}
#endif
@@ -132,7 +152,7 @@
Header h;
/* Retrieve the pubkey that matches the signature. */
- mi = rpmtsInitIterator(ts, RPMTAG_PUBKEYS, sigp->signid, sizeof(sigp->signid));
+ mi = rpmdbInitIterator(rpmtsGetRdb(ts), RPMTAG_PUBKEYS, sigp->signid, sizeof(sigp->signid));
while ((h = rpmdbNextIterator(mi)) != NULL) {
const char ** pubkeys;
int_32 pt, pc;
@@ -259,8 +279,8 @@
{
/*@-mods@*/ /* FIX: hide lazy malloc for now */
if (ts->dig == NULL) {
- ts->dig = pgpNewDig(0);
- (void) pgpSetFindPubkey(ts->dig, (int (*)(void *, void *))rpmtsFindPubkey, ts);
+ ts->dig = pgpNewDig(0);
+ (void) pgpSetFindPubkey(ts->dig, (int (*)(void *, void *))rpmtsFindPubkey, ts);
}
/*@=mods@*/
return ts->dig;
@@ -287,9 +307,9 @@
if (ts && ts->dig) {
int opx;
opx = RPMTS_OP_DIGEST;
- (void) rpmswAdd(rpmtsOp(ts, opx), pgpStatsAccumulator(ts->dig, opx));
+ (void) rpmswAdd(rpmtsOp(ts, opx), pgpStatsAccumulator(ts->dig, opx));
opx = RPMTS_OP_SIGNATURE;
- (void) rpmswAdd(rpmtsOp(ts, opx), pgpStatsAccumulator(ts->dig, opx));
+ (void) rpmswAdd(rpmtsOp(ts, opx), pgpStatsAccumulator(ts->dig, opx));
(void) rpmtsSetSig(ts, 0, 0, NULL, 0); /* XXX headerFreeData */
ts->dig = pgpFreeDig(ts->dig);
}
@@ -965,18 +985,18 @@
b = (unsigned char *) ildl;
nb = sizeof(ildl);
- (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb);
- dig->nbytes += nb;
+ (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb);
+ dig->nbytes += nb;
b = (unsigned char *) pe;
nb = (htonl(ildl[0]) * sizeof(*pe));
- (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb);
- dig->nbytes += nb;
+ (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb);
+ dig->nbytes += nb;
b = (unsigned char *) dataStart;
nb = htonl(ildl[1]);
- (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb);
- dig->nbytes += nb;
+ (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb);
+ dig->nbytes += nb;
(void) rpmswExit(op, dig->nbytes);
break;
@@ -1010,18 +1030,18 @@
b = (unsigned char *) ildl;
nb = sizeof(ildl);
- (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
- dig->nbytes += nb;
+ (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
+ dig->nbytes += nb;
b = (unsigned char *) pe;
nb = (htonl(ildl[0]) * sizeof(*pe));
- (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
- dig->nbytes += nb;
+ (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
+ dig->nbytes += nb;
b = (unsigned char *) dataStart;
nb = htonl(ildl[1]);
- (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
- dig->nbytes += nb;
+ (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
+ dig->nbytes += nb;
(void) rpmswExit(op, dig->nbytes);
break;
@@ .
patch -p0 <<'@@ .'
Index: rpm/rpmdb/rpmdb.c
============================================================================
$ cvs diff -u -r1.162 -r1.163 rpmdb.c
--- rpm/rpmdb/rpmdb.c 30 Sep 2007 17:29:05 -0000 1.162
+++ rpm/rpmdb/rpmdb.c 30 Sep 2007 22:38:30 -0000 1.163
@@ -17,12 +17,22 @@
#define _RPMEVR_INTERNAL /* XXX isInstallPrereq */
#include <rpmevr.h>
+#ifdef NOTYET
+/*@exposed@*/
+extern pgpDig rpmtsDig(void * ts)
+ /*@*/;
+extern void rpmtsCleanDig(void * ts)
+ /*@modifies ts @*/;
+#endif
+
#define _RPMDB_INTERNAL
#define _MIRE_INTERNAL
#include "rpmdb.h"
+#include "pkgio.h"
#include "fprint.h"
#include "legacy.h"
#include "header_internal.h" /* XXX for HEADERFLAG_ALLOCATED */
+
#include "debug.h"
/*@access dbiIndexSet@*/
@@ .
patch -p0 <<'@@ .'
Index: rpm/rpmdb/signature.c
============================================================================
$ cvs diff -u -r0 -r1.1 signature.c
--- /dev/null 2007-10-01 00:33:00 +0200
+++ signature.c 2007-10-01 00:38:31 +0200
@@ -0,0 +1,1344 @@
+/** \ingroup signature
+ * \file lib/signature.c
+ */
+
+#include "system.h"
+#if defined(HAVE_KEYUTILS_H)
+#include <keyutils.h>
+#endif
+
+#include "rpmio_internal.h"
+#include <rpmlib.h>
+#include <rpmmacro.h> /* XXX for rpmGetPath() */
+#include "rpmdb.h"
+
+#include "misc.h" /* XXX for dosetenv() */
+#include "legacy.h" /* XXX for mdbinfile() */
+#include <pkgio.h>
+#include "signature.h"
+#include "debug.h"
+
+/*@access FD_t@*/ /* XXX ufdio->read arg1 is void ptr */
+/*@access Header@*/ /* XXX compared with NULL */
+/*@access DIGEST_CTX@*/ /* XXX compared with NULL */
+/*@access pgpDig@*/
+/*@access pgpDigParams@*/
+
+int rpmTempFile(const char * prefix, const char ** fnptr, void * fdptr)
+{
+ const char * tpmacro = "%{?_tmppath}%{!?_tmppath:/var/tmp/}";
+ const char * tempfn = NULL;
+ const char * tfn = NULL;
+ static int _initialized = 0;
+ int temput;
+ FD_t fd = NULL;
+ int ran;
+
+ if (!prefix) prefix = "";
+
+ /* Create the temp directory if it doesn't already exist. */
+ if (!_initialized) {
+ _initialized = 1;
+ tempfn = rpmGenPath(prefix, tpmacro, NULL);
+ if (rpmioMkpath(tempfn, 0755, (uid_t) -1, (gid_t) -1))
+ goto errxit;
+ }
+
+ /* XXX should probably use mkstemp here */
+ srand(time(NULL));
+ ran = rand() % 100000;
+
+ /* maybe this should use link/stat? */
+
+ do {
+ char tfnbuf[64];
+#ifndef NOTYET
+ sprintf(tfnbuf, "rpm-tmp.%d", ran++);
+ tempfn = _free(tempfn);
+ tempfn = rpmGenPath(prefix, tpmacro, tfnbuf);
+#else
+ strcpy(tfnbuf, "rpm-tmp.XXXXXX");
+ tempfn = _free(tempfn);
+ tempfn = rpmGenPath(prefix, tpmacro, mktemp(tfnbuf));
+#endif
+
+ temput = urlPath(tempfn, &tfn);
+ if (*tfn == '\0') goto errxit;
+
+ switch (temput) {
+ case URL_IS_DASH:
+ case URL_IS_HKP:
+ goto errxit;
+ /*@notreached@*/ /*@switchbreak@*/ break;
+ case URL_IS_HTTPS:
+ case URL_IS_HTTP:
+ case URL_IS_FTP:
+ default:
+ /*@switchbreak@*/ break;
+ }
+
+ fd = Fopen(tempfn, "w+x.fdio");
+ /* XXX FIXME: errno may not be correct for ufdio */
+ } while ((fd == NULL || Ferror(fd)) && errno == EEXIST);
+
+ if (fd == NULL || Ferror(fd))
+ goto errxit;
+
+ switch(temput) {
+ case URL_IS_PATH:
+ case URL_IS_UNKNOWN:
+ { struct stat sb, sb2;
+ if (!stat(tfn, &sb) && S_ISLNK(sb.st_mode)) {
+ rpmError(RPMERR_SCRIPT, _("error creating temporary file %s\n"), tfn);
+ goto errxit;
+ }
+
+ if (sb.st_nlink != 1) {
+ rpmError(RPMERR_SCRIPT, _("error creating temporary file %s\n"), tfn);
+ goto errxit;
+ }
+
+ if (fstat(Fileno(fd), &sb2) == 0) {
+ if (sb2.st_ino != sb.st_ino || sb2.st_dev != sb.st_dev) {
+ rpmError(RPMERR_SCRIPT, _("error creating temporary file %s\n"), tfn);
+ goto errxit;
+ }
+ }
+ } break;
+ default:
+ break;
+ }
+
+ if (fnptr)
+ *fnptr = tempfn;
+ else
+ tempfn = _free(tempfn);
+ if (fdptr)
+ *(FD_t *)fdptr = fd;
+
+ return 0;
+
+errxit:
+ tempfn = _free(tempfn);
+ if (fnptr)
+ *fnptr = NULL;
+ /*@-usereleased@*/
+ if (fd != NULL) (void) Fclose(fd);
+ /*@=usereleased@*/
+ return 1;
+}
+
+
+#if defined(SUPPORT_PGP_SIGNING)
+int rpmLookupSignatureType(int action)
+{
+ /*@unchecked@*/
+ static int disabled = 0;
+ int rc = 0;
+
+ switch (action) {
+ case RPMLOOKUPSIG_DISABLE:
+ disabled = -2;
+ break;
+ case RPMLOOKUPSIG_ENABLE:
+ disabled = 0;
+ /*@fallthrough@*/
+ case RPMLOOKUPSIG_QUERY:
+ if (disabled)
+ break; /* Disabled */
+ { const char *name = rpmExpand("%{?_signature}", NULL);
+ if (!(name && *name != '\0'))
+ rc = 0;
+ else if (!xstrcasecmp(name, "none"))
+ rc = 0;
+ else if (!xstrcasecmp(name, "pgp"))
+ rc = RPMSIGTAG_PGP;
+ else if (!xstrcasecmp(name, "pgp5")) /* XXX legacy */
+ rc = RPMSIGTAG_PGP;
+ else if (!xstrcasecmp(name, "gpg"))
+ rc = RPMSIGTAG_GPG;
+ else
+ rc = -1; /* Invalid %_signature spec in macro file */
+ name = _free(name);
+ } break;
+ }
+ return rc;
+}
+
+/* rpmDetectPGPVersion() returns the absolute path to the "pgp" */
+/* executable of the requested version, or NULL when none found. */
+
+const char * rpmDetectPGPVersion(pgpVersion * pgpVer)
+{
+ /* Actually this should support having more then one pgp version. */
+ /* At the moment only one version is possible since we only */
+ /* have one %__pgp and one %_pgp_path. */
+
+ static pgpVersion saved_pgp_version = PGP_UNKNOWN;
+ const char *pgpbin = rpmGetPath("%{?__pgp}", NULL);
+
+ if (saved_pgp_version == PGP_UNKNOWN) {
+ char *pgpvbin;
+ struct stat st;
+
+ if (!(pgpbin && pgpbin[0] != '\0')) {
+ pgpbin = _free(pgpbin);
+ saved_pgp_version = -1;
+ return NULL;
+ }
+ pgpvbin = (char *)alloca(strlen(pgpbin) + sizeof("v"));
+ (void)stpcpy(stpcpy(pgpvbin, pgpbin), "v");
+
+ if (Stat(pgpvbin, &st) == 0)
+ saved_pgp_version = PGP_5;
+ else if (Stat(pgpbin, &st) == 0)
+ saved_pgp_version = PGP_2;
+ else
+ saved_pgp_version = PGP_NOTDETECTED;
+ }
+
+ if (pgpVer && pgpbin)
+ *pgpVer = saved_pgp_version;
+ return pgpbin;
+}
+#endif /* SUPPORT_PGP_SIGNING */
+
+#if defined(SUPPORT_PGP_SIGNING)
+/**
+ * Generate PGP signature(s) for a header+payload file.
+ * @param file header+payload file name
+ * @retval *sigTagp signature tag
+ * @retval *pktp signature packet(s)
+ * @retval *pktlenp signature packet(s) length
+ * @param passPhrase private key pass phrase
+ * @return 0 on success, 1 on failure
+ */
+static int makePGPSignature(const char * file, /*@unused@*/ int_32 * sigTagp,
+ /*@out@*/ byte ** pktp, /*@out@*/ int_32 * pktlenp,
+ /*@null@*/ const char * passPhrase)
+ /*@globals errno, rpmGlobalMacroContext, h_errno,
+ fileSystem, internalState @*/
+ /*@modifies errno, *pktp, *pktlenp, rpmGlobalMacroContext,
+ fileSystem, internalState @*/
+{
+ char * sigfile = alloca(1024);
+ int pid, status;
+ int inpipe[2];
+ struct stat st;
+ const char * cmd;
+ char *const *av;
+#ifdef NOTYET
+ pgpDig dig = NULL;
+ pgpDigParams sigp = NULL;
+#endif
+ int rc;
+
+ (void) stpcpy( stpcpy(sigfile, file), ".sig");
+
+ addMacro(NULL, "__plaintext_filename", NULL, file, -1);
+ addMacro(NULL, "__signature_filename", NULL, sigfile, -1);
+
+ inpipe[0] = inpipe[1] = 0;
+ (void) pipe(inpipe);
+
+ if (!(pid = fork())) {
+ const char *pgp_path = rpmExpand("%{?_pgp_path}", NULL);
+ const char *path;
+ pgpVersion pgpVer;
+
+ (void) dup2(inpipe[0], 3);
+ (void) close(inpipe[1]);
+
+ (void) dosetenv("PGPPASSFD", "3", 1);
+ if (pgp_path && *pgp_path != '\0')
+ (void) dosetenv("PGPPATH", pgp_path, 1);
+
+ /* dosetenv("PGPPASS", passPhrase, 1); */
+
+ unsetenv("MALLOC_CHECK_");
+ if ((path = rpmDetectPGPVersion(&pgpVer)) != NULL) {
+ switch(pgpVer) {
+ case PGP_2:
+ cmd = rpmExpand("%{?__pgp_sign_cmd}", NULL);
+ rc = poptParseArgvString(cmd, NULL, (const char ***)&av);
+ if (!rc)
+ rc = execve(av[0], av+1, environ);
+ break;
+ case PGP_5:
+ cmd = rpmExpand("%{?__pgp5_sign_cmd}", NULL);
+ rc = poptParseArgvString(cmd, NULL, (const char ***)&av);
+ if (!rc)
+ rc = execve(av[0], av+1, environ);
+ break;
+ case PGP_UNKNOWN:
+ case PGP_NOTDETECTED:
+ errno = ENOENT;
+ break;
+ }
+ }
+ rpmError(RPMERR_EXEC, _("Could not exec %s: %s\n"), "pgp",
+ strerror(errno));
+ _exit(RPMERR_EXEC);
+ }
+
+ delMacro(NULL, "__plaintext_filename");
+ delMacro(NULL, "__signature_filename");
+
+ (void) close(inpipe[0]);
+ if (passPhrase)
+ (void) write(inpipe[1], passPhrase, strlen(passPhrase));
+ (void) write(inpipe[1], "\n", 1);
+ (void) close(inpipe[1]);
+
+ (void)waitpid(pid, &status, 0);
+ if (!WIFEXITED(status) || WEXITSTATUS(status)) {
+ rpmError(RPMERR_SIGGEN, _("pgp failed\n"));
+ return 1;
+ }
+
+ if (Stat(sigfile, &st)) {
+ /* PGP failed to write signature */
+ if (sigfile) (void) Unlink(sigfile); /* Just in case */
+ rpmError(RPMERR_SIGGEN, _("pgp failed to write signature\n"));
+ return 1;
+ }
+
+ *pktlenp = st.st_size;
+ rpmMessage(RPMMESS_DEBUG, D_("PGP sig size: %d\n"), *pktlenp);
+ *pktp = xmalloc(*pktlenp);
+
+ { FD_t fd;
+
+ rc = 0;
+ fd = Fopen(sigfile, "r.fdio");
+ if (fd != NULL && !Ferror(fd)) {
+ rc = timedRead(fd, (void *)*pktp, *pktlenp);
+ if (sigfile) (void) Unlink(sigfile);
+ (void) Fclose(fd);
+ }
+ if (rc != *pktlenp) {
+ *pktp = _free(*pktp);
+ rpmError(RPMERR_SIGGEN, _("unable to read the signature\n"));
+ return 1;
+ }
+ }
+
+ rpmMessage(RPMMESS_DEBUG, D_("Got %d bytes of PGP sig\n"), *pktlenp);
+
+#ifdef NOTYET
+ /* Parse the signature, change signature tag as appropriate. */
+ dig = pgpNewDig(0);
+
+ (void) pgpPrtPkts(*pktp, *pktlenp, dig, 0);
+ sigp = pgpGetSignature(dig);
+
+ dig = pgpFreeDig(dig);
+#endif
+
+ return 0;
+}
+#endif /* SUPPORT_PGP_SIGNING */
+
+/**
+ * Generate GPG signature(s) for a header+payload file.
+ * @param file header+payload file name
+ * @retval *sigTagp signature tag
+ * @retval *pktp signature packet(s)
+ * @retval *pktlenp signature packet(s) length
+ * @param passPhrase private key pass phrase
+ * @return 0 on success, 1 on failure
+ */
+static int makeGPGSignature(const char * file, int_32 * sigTagp,
+ /*@out@*/ byte ** pktp, /*@out@*/ int_32 * pktlenp,
+ /*@null@*/ const char * passPhrase)
+ /*@globals rpmGlobalMacroContext, h_errno,
+ fileSystem, internalState @*/
+ /*@modifies *pktp, *pktlenp, *sigTagp, rpmGlobalMacroContext,
+ fileSystem, internalState @*/
+{
+ char * sigfile = alloca(strlen(file)+sizeof(".sig"));
+ int pid, status;
+ int inpipe[2];
+ FILE * fpipe;
+ struct stat st;
+ const char * cmd;
+ char *const *av;
+ pgpDig dig = NULL;
+ pgpDigParams sigp = NULL;
+ const char * pw = NULL;
+ int rc;
+
+ (void) stpcpy( stpcpy(sigfile, file), ".sig");
+
+ addMacro(NULL, "__plaintext_filename", NULL, file, -1);
+ addMacro(NULL, "__signature_filename", NULL, sigfile, -1);
+
+ inpipe[0] = inpipe[1] = 0;
+ (void) pipe(inpipe);
+
+ if (!(pid = fork())) {
+ const char *gpg_path = rpmExpand("%{?_gpg_path}", NULL);
+
+ (void) dup2(inpipe[0], 3);
+ (void) close(inpipe[1]);
+
+ if (gpg_path && *gpg_path != '\0')
+ (void) dosetenv("GNUPGHOME", gpg_path, 1);
+
+ unsetenv("MALLOC_CHECK_");
+ cmd = rpmExpand("%{?__gpg_sign_cmd}", NULL);
+ rc = poptParseArgvString(cmd, NULL, (const char ***)&av);
+ if (!rc)
+ rc = execve(av[0], av+1, environ);
+
+ rpmError(RPMERR_EXEC, _("Could not exec %s: %s\n"), "gpg",
+ strerror(errno));
+ _exit(RPMERR_EXEC);
+ }
+
+ delMacro(NULL, "__plaintext_filename");
+ delMacro(NULL, "__signature_filename");
+
+#if defined(HAVE_KEYUTILS_H)
+ if (!strcmp(passPhrase, "@u user rpm:passwd")) {
+ key_serial_t keyring = KEY_SPEC_PROCESS_KEYRING;
+ long key;
+ int xx;
+
+/*@-moduncon@*/
+ key = keyctl_search(keyring, "user", "rpm:passwd", 0);
+ if ((xx = keyctl_read_alloc(key, (void **)&pw)) < 0) {
+ rpmError(RPMERR_SIGGEN, _("Failed %s(%d) key(0x%lx): %s\n"),
+ "keyctl_read_alloc of key", xx, key, strerror(errno));
+ return 1;
+ }
+/*@=moduncon@*/
+ } else
+#endif
+ pw = passPhrase;
+
+ fpipe = fdopen(inpipe[1], "w");
+ (void) close(inpipe[0]);
+ if (fpipe) {
+ fprintf(fpipe, "%s\n", (pw ? pw : ""));
+ (void) fclose(fpipe);
+ }
+/*@-mods@*/
+ if (pw && pw != passPhrase) {
+ (void) memset((void *)pw, 0, strlen(pw));
+/*@-temptrans@*/ /* XXX mixed use in variable */
+ pw = _free(pw);
+/*@=temptrans@*/
+ }
+/*@=mods@*/
+
+ (void) waitpid(pid, &status, 0);
+ if (!WIFEXITED(status) || WEXITSTATUS(status)) {
+ rpmError(RPMERR_SIGGEN, _("gpg exec failed (%d)\n"), WEXITSTATUS(status));
+ return 1;
+ }
+
+ if (Stat(sigfile, &st)) {
+ /* GPG failed to write signature */
+ if (sigfile) (void) Unlink(sigfile); /* Just in case */
+ rpmError(RPMERR_SIGGEN, _("gpg failed to write signature\n"));
+ return 1;
+ }
+
+ *pktlenp = st.st_size;
+ rpmMessage(RPMMESS_DEBUG, D_("GPG sig size: %d\n"), *pktlenp);
+ *pktp = xmalloc(*pktlenp);
+
+ { FD_t fd;
+
+ rc = 0;
+ fd = Fopen(sigfile, "r.fdio");
+ if (fd != NULL && !Ferror(fd)) {
+ rc = timedRead(fd, (void *)*pktp, *pktlenp);
+ if (sigfile) (void) Unlink(sigfile);
+ (void) Fclose(fd);
+ }
+ if (rc != *pktlenp) {
+ *pktp = _free(*pktp);
+ rpmError(RPMERR_SIGGEN, _("unable to read the signature\n"));
+ return 1;
+ }
+ }
+
+ rpmMessage(RPMMESS_DEBUG, D_("Got %d bytes of GPG sig\n"), *pktlenp);
+
+ /* Parse the signature, change signature tag as appropriate. */
+ dig = pgpNewDig(0);
+
+ (void) pgpPrtPkts(*pktp, *pktlenp, dig, 0);
+ sigp = pgpGetSignature(dig);
+
+ /* Identify the type of signature being returned. */
+ switch (*sigTagp) {
+ case RPMSIGTAG_SIZE:
+ case RPMSIGTAG_MD5:
+ case RPMSIGTAG_SHA1:
+ break;
+#if defined(SUPPORT_RPMV3_SIGN_DSA) || defined(SUPPORT_RPMV3_SIGN_RSA)
+ case RPMSIGTAG_GPG:
+ /* XXX check hash algorithm too? */
+ if (sigp->pubkey_algo == PGPPUBKEYALGO_RSA)
+ *sigTagp = RPMSIGTAG_PGP;
+ break;
+#endif
+#if defined(SUPPORT_RPMV3_SIGN_DSA) || defined(SUPPORT_RPMV3_SIGN_RSA)
+ case RPMSIGTAG_PGP5: /* XXX legacy */
+ case RPMSIGTAG_PGP:
+ if (sigp->pubkey_algo == PGPPUBKEYALGO_DSA)
+ *sigTagp = RPMSIGTAG_GPG;
+ break;
+#endif
+ case RPMSIGTAG_DSA:
+ /* XXX check hash algorithm too? */
+ if (sigp->pubkey_algo == PGPPUBKEYALGO_RSA)
+ *sigTagp = RPMSIGTAG_RSA;
+ break;
+ case RPMSIGTAG_RSA:
+ if (sigp->pubkey_algo == PGPPUBKEYALGO_DSA)
+ *sigTagp = RPMSIGTAG_DSA;
+ break;
+ }
+
+ dig = pgpFreeDig(dig);
+
+ return 0;
+}
+
+/**
+ * Generate header only signature(s) from a header+payload file.
+ * @param sigh signature header
+ * @param file header+payload file name
+ * @param sigTag type of signature(s) to add
+ * @param passPhrase private key pass phrase
+ * @return 0 on success, -1 on failure
+ */
+static int makeHDRSignature(Header sigh, const char * file, int_32 sigTag,
+ /*@null@*/ const char * passPhrase)
+ /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
+ /*@modifies sigh, sigTag, rpmGlobalMacroContext, fileSystem, internalState @*/
+{
+ Header h = NULL;
+ FD_t fd = NULL;
+ byte * pkt;
+ int_32 pktlen;
+ const char * fn = NULL;
+ const char * SHA1 = NULL;
+ int ret = -1; /* assume failure. */
+
+ switch (sigTag) {
+ case RPMSIGTAG_SIZE:
+ case RPMSIGTAG_MD5:
+ case RPMSIGTAG_PGP5: /* XXX legacy */
+ case RPMSIGTAG_PGP:
+ case RPMSIGTAG_GPG:
+ goto exit;
+ /*@notreached@*/ break;
+ case RPMSIGTAG_SHA1:
+ fd = Fopen(file, "r.fdio");
+ if (fd == NULL || Ferror(fd))
+ goto exit;
+ h = headerRead(fd);
+ if (h == NULL)
+ goto exit;
+ (void) Fclose(fd); fd = NULL;
+
+ if (headerIsEntry(h, RPMTAG_HEADERIMMUTABLE)) {
+ unsigned char * hmagic = NULL;
+ size_t nmagic = 0;
+ DIGEST_CTX ctx;
+ void * uh;
+ int_32 uht, uhc;
+
+ if (!headerGetEntry(h, RPMTAG_HEADERIMMUTABLE, &uht, &uh, &uhc)
+ || uh == NULL)
+ {
+ h = headerFree(h);
+ goto exit;
+ }
+ (void) headerGetMagic(NULL, &hmagic, &nmagic);
+ ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
+ if (hmagic && nmagic > 0)
+ (void) rpmDigestUpdate(ctx, hmagic, nmagic);
+ (void) rpmDigestUpdate(ctx, uh, uhc);
+ (void) rpmDigestFinal(ctx, &SHA1, NULL, 1);
+ uh = headerFreeData(uh, uht);
+ }
+ h = headerFree(h);
+
+ if (SHA1 == NULL)
+ goto exit;
+ if (!headerAddEntry(sigh, RPMSIGTAG_SHA1, RPM_STRING_TYPE, SHA1, 1))
+ goto exit;
+ ret = 0;
+ break;
+ case RPMSIGTAG_DSA:
+ fd = Fopen(file, "r.fdio");
+ if (fd == NULL || Ferror(fd))
+ goto exit;
+ h = headerRead(fd);
+ if (h == NULL)
+ goto exit;
+ (void) Fclose(fd); fd = NULL;
+ if (rpmTempFile(NULL, &fn, &fd))
+ goto exit;
+ if (headerWrite(fd, h))
+ goto exit;
+ (void) Fclose(fd); fd = NULL;
+ if (makeGPGSignature(fn, &sigTag, &pkt, &pktlen, passPhrase)
+ || !headerAddEntry(sigh, sigTag, RPM_BIN_TYPE, pkt, pktlen))
+ goto exit;
+ ret = 0;
+ break;
+#if defined(SUPPORT_PGP_SIGNING)
+ case RPMSIGTAG_RSA:
+ fd = Fopen(file, "r.fdio");
+ if (fd == NULL || Ferror(fd))
+ goto exit;
+ h = headerRead(fd);
+ if (h == NULL)
+ goto exit;
+ (void) Fclose(fd); fd = NULL;
+ if (rpmTempFile(NULL, &fn, &fd))
+ goto exit;
+ if (headerWrite(fd, h))
+ goto exit;
+ (void) Fclose(fd); fd = NULL;
+ if (makePGPSignature(fn, &sigTag, &pkt, &pktlen, passPhrase)
+ || !headerAddEntry(sigh, sigTag, RPM_BIN_TYPE, pkt, pktlen))
+ goto exit;
+ ret = 0;
+ break;
+#endif /* SUPPORT_PGP_SIGNING */
+ }
+
+exit:
+ if (fn) {
+ (void) Unlink(fn);
+ fn = _free(fn);
+ }
+ SHA1 = _free(SHA1);
+ h = headerFree(h);
+ if (fd != NULL) (void) Fclose(fd);
+ return ret;
+}
+
+int rpmAddSignature(Header sigh, const char * file, int_32 sigTag,
+ const char * passPhrase)
+{
+ struct stat st;
+ byte * pkt;
+ int_32 pktlen;
+ int ret = -1; /* assume failure. */
+
+ switch (sigTag) {
+ case RPMSIGTAG_SIZE:
+ if (Stat(file, &st) != 0)
+ break;
+ pktlen = st.st_size;
+ if (!headerAddEntry(sigh, sigTag, RPM_INT32_TYPE, &pktlen, 1))
+ break;
+ ret = 0;
+ break;
+ case RPMSIGTAG_MD5:
+ pktlen = 16;
+ pkt = memset(alloca(pktlen), 0, pktlen);
+ if (dodigest(PGPHASHALGO_MD5, file, pkt, 0, NULL)
+ || !headerAddEntry(sigh, sigTag, RPM_BIN_TYPE, pkt, pktlen))
+ break;
+ ret = 0;
+ break;
+#if defined(SUPPORT_PGP_SIGNING)
+ case RPMSIGTAG_PGP5: /* XXX legacy */
+ case RPMSIGTAG_PGP:
+#if defined(SUPPORT_RPMV3_SIGN_RSA)
+ if (makePGPSignature(file, &sigTag, &pkt, &pktlen, passPhrase)
+ || !headerAddEntry(sigh, sigTag, RPM_BIN_TYPE, pkt, pktlen))
+ break;
+ /* XXX Piggyback a header-only RSA signature as well. */
+#endif
+#ifdef NOTYET /* XXX needs hdrmd5ctx, like hdrsha1ctx. */
+ ret = makeHDRSignature(sigh, file, RPMSIGTAG_RSA, passPhrase);
+#endif
+ ret = 0;
+ break;
+#endif /* SUPPORT_PGP_SIGNING */
+ case RPMSIGTAG_GPG:
+#if defined(SUPPORT_RPMV3_SIGN_DSA)
+ if (makeGPGSignature(file, &sigTag, &pkt, &pktlen, passPhrase)
+ || !headerAddEntry(sigh, sigTag, RPM_BIN_TYPE, pkt, pktlen))
+ break;
+ /* XXX Piggyback a header-only DSA signature as well. */
+#endif
+ ret = makeHDRSignature(sigh, file, RPMSIGTAG_DSA, passPhrase);
+ break;
+ case RPMSIGTAG_RSA:
+ case RPMSIGTAG_DSA:
+ case RPMSIGTAG_SHA1:
+ ret = makeHDRSignature(sigh, file, sigTag, passPhrase);
+ break;
+ }
+
+ return ret;
+}
+
+int rpmCheckPassPhrase(const char * passPhrase)
+{
+ const char *pw;
+ int p[2];
+ int pid, status;
+ int rc;
+ int xx;
+
+ p[0] = p[1] = 0;
+ xx = pipe(p);
+
+ if (!(pid = fork())) {
+ const char * cmd;
+ char *const *av;
+ int fdno;
+
+ xx = close(STDIN_FILENO);
+ xx = close(STDOUT_FILENO);
+ xx = close(p[1]);
+ if (!rpmIsVerbose())
+ xx = close(STDERR_FILENO);
+ if ((fdno = open("/dev/null", O_RDONLY)) != STDIN_FILENO) {
+ xx = dup2(fdno, STDIN_FILENO);
+ xx = close(fdno);
+ }
+ if ((fdno = open("/dev/null", O_WRONLY)) != STDOUT_FILENO) {
+ xx = dup2(fdno, STDOUT_FILENO);
+ xx = close(fdno);
+ }
+ xx = dup2(p[0], 3);
+
+ unsetenv("MALLOC_CHECK_");
+#if defined(SUPPORT_PGP_SIGNING)
+ if (use_pgp) {
+ const char *pgp_path = rpmExpand("%{?_pgp_path}", NULL);
+ const char *path;
+ pgpVersion pgpVer;
+
+ (void) dosetenv("PGPPASSFD", "3", 1);
+ if (pgp_path && *pgp_path != '\0')
+ xx = dosetenv("PGPPATH", pgp_path, 1);
+
+ if ((path = rpmDetectPGPVersion(&pgpVer)) != NULL) {
+ switch(pgpVer) {
+ case PGP_2:
+ cmd = rpmExpand("%{?__pgp_check_password_cmd}", NULL);
+ rc = poptParseArgvString(cmd, NULL, (const char ***)&av);
+ if (!rc)
+ rc = execve(av[0], av+1, environ);
+ /*@innerbreak@*/ break;
+ case PGP_5: /* XXX legacy */
+ cmd = rpmExpand("%{?__pgp5_check_password_cmd}", NULL);
+ rc = poptParseArgvString(cmd, NULL, (const char ***)&av);
+ if (!rc)
+ rc = execve(av[0], av+1, environ);
+ /*@innerbreak@*/ break;
+ case PGP_UNKNOWN:
+ case PGP_NOTDETECTED:
+ /*@innerbreak@*/ break;
+ }
+ }
+ rpmError(RPMERR_EXEC, _("Could not exec %s: %s\n"), "pgp",
+ strerror(errno));
+ _exit(RPMERR_EXEC);
+ } else
+#endif /* SUPPORT_PGP_SIGNING */
+ { const char *gpg_path = rpmExpand("%{?_gpg_path}", NULL);
+
+ if (gpg_path && *gpg_path != '\0')
+ (void) dosetenv("GNUPGHOME", gpg_path, 1);
+
+ cmd = rpmExpand("%{?__gpg_check_password_cmd}", NULL);
+ rc = poptParseArgvString(cmd, NULL, (const char ***)&av);
+ if (!rc)
+ rc = execve(av[0], av+1, environ);
+
+ rpmError(RPMERR_EXEC, _("Could not exec %s: %s\n"), "gpg",
+ strerror(errno));
+ }
+ }
+
+#if defined(HAVE_KEYUTILS_H)
+ if (!strcmp(passPhrase, "@u user rpm:passwd")) {
+ long key;
+ key_serial_t keyring = KEY_SPEC_PROCESS_KEYRING;
+
+/*@-moduncon@*/
+ key = keyctl_search(keyring, "user", "rpm:passwd", 0);
+ if ((xx = keyctl_read_alloc(key, (void **)&pw)) < 0) {
+ rpmError(RPMERR_SIGGEN, _("Failed %s(%d) key(0x%lx): %s\n"),
+ "keyctl_read_alloc of key", xx, key, strerror(errno));
+ return 1;
+ }
+/*@=moduncon@*/
+ } else
+#endif
+ pw = passPhrase;
+
+ xx = close(p[0]);
+ xx = write(p[1], pw, strlen(pw));
+ xx = write(p[1], "\n", 1);
+ xx = close(p[1]);
+
+/*@-mods@*/
+ if (pw && pw != passPhrase) {
+ (void) memset((void *)pw, 0, strlen(pw));
+/*@-temptrans@*/ /* XXX mixed use in variable */
+ pw = _free(pw);
+/*@=temptrans@*/
+ }
+/*@=mods@*/
+
+ (void) waitpid(pid, &status, 0);
+
+ return ((!WIFEXITED(status) || WEXITSTATUS(status)) ? 1 : 0);
+}
+
+static /*@observer@*/ const char * rpmSigString(rpmRC res)
+ /*@*/
+{
+ const char * str;
+ switch (res) {
+ case RPMRC_OK: str = "OK"; break;
+ case RPMRC_FAIL: str = "BAD"; break;
+ case RPMRC_NOKEY: str = "NOKEY"; break;
+ case RPMRC_NOTTRUSTED: str = "NOTRUSTED"; break;
+ default:
+ case RPMRC_NOTFOUND: str = "UNKNOWN"; break;
+ }
+ return str;
+}
+
+static rpmRC
+verifySizeSignature(const pgpDig dig, /*@out@*/ char * t)
+ /*@modifies *t @*/
+{
+ const void * sig = pgpGetSig(dig);
+ rpmRC res;
+ int_32 size = 0x7fffffff;
+
+ *t = '\0';
+ t = stpcpy(t, _("Header+Payload size: "));
+
+ if (sig == NULL || dig == NULL || dig->nbytes == 0) {
+ res = RPMRC_NOKEY;
+ t = stpcpy(t, rpmSigString(res));
+ goto exit;
+ }
+
+ memcpy(&size, sig, sizeof(size));
+
+ if (size != dig->nbytes) {
+ res = RPMRC_FAIL;
+ t = stpcpy(t, rpmSigString(res));
+ sprintf(t, " Expected(%d) != (%d)\n", (int)size, (int)dig->nbytes);
+ } else {
+ res = RPMRC_OK;
+ t = stpcpy(t, rpmSigString(res));
+ sprintf(t, " (%d)", (int)dig->nbytes);
+ }
+
+exit:
+ t = stpcpy(t, "\n");
+ return res;
+}
+
+static rpmRC
+verifyMD5Signature(const pgpDig dig, /*@out@*/ char * t,
+ /*@null@*/ DIGEST_CTX md5ctx)
+ /*@globals internalState @*/
+ /*@modifies *t, internalState @*/
+{
+ const void * sig = pgpGetSig(dig);
+ int_32 siglen = pgpGetSiglen(dig);
+ rpmRC res;
+ byte * md5sum = NULL;
+ size_t md5len = 0;
+
+ *t = '\0';
+ t = stpcpy(t, _("MD5 digest: "));
+
+ if (md5ctx == NULL || sig == NULL || dig == NULL) {
+ res = RPMRC_NOKEY;
+ t = stpcpy(t, rpmSigString(res));
+ goto exit;
+ }
+
+ { rpmop op = pgpStatsAccumulator(dig, 10); /* RPMTS_OP_DIGEST */
+ (void) rpmswEnter(op, 0);
+ (void) rpmDigestFinal(rpmDigestDup(md5ctx), &md5sum, &md5len, 0);
+ (void) rpmswExit(op, 0);
+ op->count--; /* XXX one too many */
+ }
+
+ if (md5len != siglen || memcmp(md5sum, sig, md5len)) {
+ res = RPMRC_FAIL;
+ t = stpcpy(t, rpmSigString(res));
+ t = stpcpy(t, " Expected(");
+ (void) pgpHexCvt(t, sig, siglen);
+ t += strlen(t);
+ t = stpcpy(t, ") != (");
+ } else {
+ res = RPMRC_OK;
+ t = stpcpy(t, rpmSigString(res));
+ t = stpcpy(t, " (");
+ }
+ (void) pgpHexCvt(t, md5sum, md5len);
+ t += strlen(t);
+ t = stpcpy(t, ")");
+
+exit:
+ md5sum = _free(md5sum);
+ t = stpcpy(t, "\n");
+ return res;
+}
+
+/**
+ * Verify header immutable region SHA1 digest.
+ * @param dig container
+ * @retval t verbose success/failure text
+ * @param sha1ctx
+ * @return RPMRC_OK on success
+ */
+static rpmRC
+verifySHA1Signature(const pgpDig dig, /*@out@*/ char * t,
+ /*@null@*/ DIGEST_CTX sha1ctx)
+ /*@globals internalState @*/
+ /*@modifies *t, internalState @*/
+{
+ const void * sig = pgpGetSig(dig);
+#ifdef NOTYET
+ int_32 siglen = pgpGetSiglen(dig);
+#endif
+ rpmRC res;
+ const char * SHA1 = NULL;
+
+ *t = '\0';
+ t = stpcpy(t, _("Header SHA1 digest: "));
+
+ if (sha1ctx == NULL || sig == NULL || dig == NULL) {
+ res = RPMRC_NOKEY;
+ t = stpcpy(t, rpmSigString(res));
+ goto exit;
+ }
+
+ { rpmop op = pgpStatsAccumulator(dig, 10); /* RPMTS_OP_DIGEST */
+ (void) rpmswEnter(op, 0);
+ (void) rpmDigestFinal(rpmDigestDup(sha1ctx), &SHA1, NULL, 1);
+ (void) rpmswExit(op, 0);
+ }
+
+ if (SHA1 == NULL || strlen(SHA1) != strlen(sig) || strcmp(SHA1, sig)) {
+ res = RPMRC_FAIL;
+ t = stpcpy(t, rpmSigString(res));
+ t = stpcpy(t, " Expected(");
+ t = stpcpy(t, sig);
+ t = stpcpy(t, ") != (");
+ } else {
+ res = RPMRC_OK;
+ t = stpcpy(t, rpmSigString(res));
+ t = stpcpy(t, " (");
+ }
+ if (SHA1)
+ t = stpcpy(t, SHA1);
+ t = stpcpy(t, ")");
+
+exit:
+ SHA1 = _free(SHA1);
+ t = stpcpy(t, "\n");
+ return res;
+}
+
+/**
+ * Convert hex to binary nibble.
+ * @param c hex character
+ * @return binary nibble
+ */
+static inline unsigned char nibble(char c)
+ /*@*/
+{
+ if (c >= '0' && c <= '9')
+ return (c - '0');
+ if (c >= 'A' && c <= 'F')
+ return (c - 'A') + 10;
+ if (c >= 'a' && c <= 'f')
+ return (c - 'a') + 10;
+ return 0;
+}
+
+/**
+ * Verify RSA signature.
+ * @param dig container
+ * @retval t verbose success/failure text
+ * @param md5ctx
+ * @return RPMRC_OK on success
+ */
+static rpmRC
+verifyRSASignature(pgpDig dig, /*@out@*/ char * t,
+ /*@null@*/ DIGEST_CTX md5ctx)
+ /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
+ /*@modifies dig, *t, rpmGlobalMacroContext, fileSystem, internalState */
+{
+ const void * sig = pgpGetSig(dig);
+#ifdef NOTYET
+ int_32 siglen = pgpGetSiglen(dig);
+#endif
+ int_32 sigtag = pgpGetSigtag(dig);
+ pgpDigParams sigp = pgpGetSignature(dig);
+ const char * prefix = NULL;
+ rpmRC res = RPMRC_OK;
+ int xx;
+
+assert(dig != NULL);
+assert(sigp != NULL);
+ *t = '\0';
+ if (dig != NULL && dig->hdrmd5ctx == md5ctx)
+ t = stpcpy(t, _("Header "));
+ *t++ = 'V';
+ switch (sigp->version) {
+ case 3: *t++ = '3'; break;
+ case 4: *t++ = '4'; break;
+ }
+
+ if (md5ctx == NULL || sig == NULL || dig == NULL || sigp == NULL) {
+ res = RPMRC_NOKEY;
+ }
+
+ /* Verify the desired signature match. */
+ switch (sigp->pubkey_algo) {
+ case PGPPUBKEYALGO_RSA:
+ if (sigtag == RPMSIGTAG_RSA
+#if defined(SUPPORT_RPMV3_VERIFY_RSA)
+ || sigtag == RPMSIGTAG_PGP
+ || sigtag == RPMSIGTAG_PGP5
+#endif
+ )
+ break;
+ /*@fallthrough@*/
+ default:
+ res = RPMRC_NOKEY;
+ break;
+ }
+
+ /* Verify the desired hash match. */
+ /* XXX Values from PKCS#1 v2.1 (aka RFC-3447) */
+ switch (sigp->hash_algo) {
+ case PGPHASHALGO_MD5:
+ t = stpcpy(t, " RSA/MD5");
+ prefix = "3020300c06082a864886f70d020505000410";
+ break;
+ case PGPHASHALGO_SHA1:
+ t = stpcpy(t, " RSA/SHA1");
+ prefix = "3021300906052b0e03021a05000414";
+ break;
+ case PGPHASHALGO_RIPEMD160:
+ t = stpcpy(t, " RSA/RIPEMD160");
+ prefix = "3021300906052b2403020105000414";
+ break;
+ case PGPHASHALGO_MD2:
+ t = stpcpy(t, " RSA/MD2");
+ prefix = "3020300c06082a864886f70d020205000410";
+ break;
+ case PGPHASHALGO_TIGER192:
+ t = stpcpy(t, " RSA/TIGER192");
+ prefix = "3029300d06092b06010401da470c0205000418";
+ break;
+ case PGPHASHALGO_HAVAL_5_160:
+ res = RPMRC_NOKEY;
+ prefix = NULL;
+ break;
+ case PGPHASHALGO_SHA256:
+ t = stpcpy(t, " RSA/SHA256");
+ prefix = "3031300d060960864801650304020105000420";
+ break;
+ case PGPHASHALGO_SHA384:
+ t = stpcpy(t, " RSA/SHA384");
+ prefix = "3041300d060960864801650304020205000430";
+ break;
+ case PGPHASHALGO_SHA512:
+ t = stpcpy(t, " RSA/SHA512");
+ prefix = "3051300d060960864801650304020305000440";
+ break;
+ default:
+ res = RPMRC_NOKEY;
+ prefix = NULL;
+ break;
+ }
+
+ t = stpcpy(t, _(" signature: "));
+ if (res != RPMRC_OK) {
+ goto exit;
+ }
+
+assert(md5ctx != NULL); /* XXX can't happen. */
+ { rpmop op = pgpStatsAccumulator(dig, 10); /* RPMTS_OP_DIGEST */
+ DIGEST_CTX ctx;
+ byte signhash16[2];
+ const char * s;
+
+ (void) rpmswEnter(op, 0);
+ ctx = rpmDigestDup(md5ctx);
+ if (sigp->hash != NULL)
+ xx = rpmDigestUpdate(ctx, sigp->hash, sigp->hashlen);
+
+#ifdef NOTYET /* XXX not for binary/text signatures as in packages. */
+ if (!(sigp->sigtype == PGPSIGTYPE_BINARY || sigp->sigtype == PGP_SIGTYPE_TEXT)) {
+ int nb = dig->nbytes + sigp->hashlen;
+ byte trailer[6];
+ nb = htonl(nb);
+ trailer[0] = 0x4;
+ trailer[1] = 0xff;
+ memcpy(trailer+2, &nb, sizeof(nb));
+ xx = rpmDigestUpdate(ctx, trailer, sizeof(trailer));
+ }
+#endif
+
+ xx = rpmDigestFinal(ctx, (void **)&dig->md5, &dig->md5len, 1);
+ (void) rpmswExit(op, sigp->hashlen);
+ op->count--; /* XXX one too many */
+
+ /* Compare leading 16 bits of digest for quick check. */
+ s = dig->md5;
+ signhash16[0] = (nibble(s[0]) << 4) | nibble(s[1]);
+ signhash16[1] = (nibble(s[2]) << 4) | nibble(s[3]);
+ if (memcmp(signhash16, sigp->signhash16, sizeof(signhash16))) {
+ res = RPMRC_FAIL;
+ goto exit;
+ }
+ }
+
+ /* Generate RSA modulus parameter. */
+ { unsigned int nbits = MP_WORDS_TO_BITS(dig->c.size);
+ unsigned int nb = (nbits + 7) >> 3;
+ const char * hexstr;
+ char * tt;
+
+assert(prefix != NULL);
+ hexstr = tt = xmalloc(2 * nb + 1);
+ memset(tt, 'f', (2 * nb));
+ tt[0] = '0'; tt[1] = '0';
+ tt[2] = '0'; tt[3] = '1';
+ tt += (2 * nb) - strlen(prefix) - strlen(dig->md5) - 2;
+ *tt++ = '0'; *tt++ = '0';
+ tt = stpcpy(tt, prefix);
+ tt = stpcpy(tt, dig->md5);
+
+/*@-moduncon -noeffectuncon @*/
+ mpnzero(&dig->rsahm); (void) mpnsethex(&dig->rsahm, hexstr);
+/*@=moduncon =noeffectuncon @*/
+
+ hexstr = _free(hexstr);
+
+ }
+
+ /* Retrieve the matching public key. */
+ res = pgpFindPubkey(dig);
+ if (res != RPMRC_OK)
+ goto exit;
+
+ { rpmop op = pgpStatsAccumulator(dig, 11); /* RPMTS_OP_SIGNATURE */
+ (void) rpmswEnter(op, 0);
+/*@-moduncon@*/
+#if defined(HAVE_BEECRYPT_API_H)
+ xx = rsavrfy(&dig->rsa_pk.n, &dig->rsa_pk.e, &dig->c, &dig->rsahm);
+#else
+ xx = rsavrfy(&dig->rsa_pk, &dig->rsahm, &dig->c);
+#endif
+/*@=moduncon@*/
+ (void) rpmswExit(op, 0);
+ res = (xx ? RPMRC_OK : RPMRC_FAIL);
+ }
+
+exit:
+ t = stpcpy(t, rpmSigString(res));
+ if (sigp != NULL) {
+ t = stpcpy(t, ", key ID ");
+ (void) pgpHexCvt(t, sigp->signid+4, sizeof(sigp->signid)-4);
+ t += strlen(t);
+ }
+ t = stpcpy(t, "\n");
+ return res;
+}
+
+/**
+ * Verify DSA signature.
+ * @param dig container
+ * @retval t verbose success/failure text
+ * @param sha1ctx
+ * @return RPMRC_OK on success
+ */
+static rpmRC
+verifyDSASignature(pgpDig dig, /*@out@*/ char * t,
+ /*@null@*/ DIGEST_CTX sha1ctx)
+ /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
+ /*@modifies dig, *t, rpmGlobalMacroContext, fileSystem, internalState */
+{
+ const void * sig = pgpGetSig(dig);
+#ifdef NOTYET
+ int_32 siglen = pgpGetSiglen(dig);
+#endif
+ int_32 sigtag = pgpGetSigtag(dig);
+ pgpDigParams sigp = pgpGetSignature(dig);
+ rpmRC res;
+ int xx;
+
+assert(dig != NULL);
+assert(sigp != NULL);
+ *t = '\0';
+ if (dig != NULL && dig->hdrsha1ctx == sha1ctx)
+ t = stpcpy(t, _("Header "));
+ *t++ = 'V';
+ switch (sigp->version) {
+ case 3: *t++ = '3'; break;
+ case 4: *t++ = '4'; break;
+ }
+ t = stpcpy(t, _(" DSA signature: "));
+
+ if (sha1ctx == NULL || sig == NULL || dig == NULL || sigp == NULL) {
+ res = RPMRC_NOKEY;
+ goto exit;
+ }
+
+ /* XXX sanity check on sigtag and signature agreement. */
+ if (!(
+#if defined(SUPPORT_RPMV3_VERIFY_DSA)
+ (sigtag == RPMSIGTAG_GPG || sigtag == RPMSIGTAG_DSA)
+#else
+ (sigtag == RPMSIGTAG_DSA)
+#endif
+ && sigp->pubkey_algo == PGPPUBKEYALGO_DSA
+ && sigp->hash_algo == PGPHASHALGO_SHA1))
+ {
+ res = RPMRC_NOKEY;
+ goto exit;
+ }
+
+ { rpmop op = pgpStatsAccumulator(dig, 10); /* RPMTS_OP_DIGEST */
+ DIGEST_CTX ctx;
+ byte signhash16[2];
+
+ (void) rpmswEnter(op, 0);
+ ctx = rpmDigestDup(sha1ctx);
+ if (sigp->hash != NULL)
+ xx = rpmDigestUpdate(ctx, sigp->hash, sigp->hashlen);
+
+ if (sigp->version == 4) {
+ int nb = sigp->hashlen;
+ byte trailer[6];
+ nb = htonl(nb);
+ trailer[0] = sigp->version;
+ trailer[1] = 0xff;
+ memcpy(trailer+2, &nb, sizeof(nb));
+ xx = rpmDigestUpdate(ctx, trailer, sizeof(trailer));
+ }
+ xx = rpmDigestFinal(ctx, (void **)&dig->sha1, &dig->sha1len, 1);
+ (void) rpmswExit(op, sigp->hashlen);
+ op->count--; /* XXX one too many */
+
+/*@-moduncon -noeffectuncon @*/
+ mpnzero(&dig->hm); (void) mpnsethex(&dig->hm, dig->sha1);
+/*@=moduncon =noeffectuncon @*/
+
+ /* Compare leading 16 bits of digest for quick check. */
+ signhash16[0] = (*dig->hm.data >> 24) & 0xff;
+ signhash16[1] = (*dig->hm.data >> 16) & 0xff;
+ if (memcmp(signhash16, sigp->signhash16, sizeof(signhash16))) {
+ res = RPMRC_FAIL;
+ goto exit;
+ }
+ }
+
+ /* Retrieve the matching public key. */
+ res = pgpFindPubkey(dig);
+ if (res != RPMRC_OK)
+ goto exit;
+
+ { rpmop op = pgpStatsAccumulator(dig, 11); /* RPMTS_OP_SIGNATURE */
+ (void) rpmswEnter(op, 0);
+/*@-moduncon@*/
+ if (dsavrfy(&dig->p, &dig->q, &dig->g,
+ &dig->hm, &dig->y, &dig->r, &dig->s))
+ res = RPMRC_OK;
+ else
+ res = RPMRC_FAIL;
+/*@=moduncon@*/
+ (void) rpmswExit(op, 0);
+ }
+
+exit:
+ t = stpcpy(t, rpmSigString(res));
+ if (sigp != NULL) {
+ t = stpcpy(t, ", key ID ");
+ (void) pgpHexCvt(t, sigp->signid+4, sizeof(sigp->signid)-4);
+ t += strlen(t);
+ }
+ t = stpcpy(t, "\n");
+ return res;
+}
+
+rpmRC
+rpmVerifySignature(void * _dig, char * result)
+{
+ pgpDig dig = _dig;
+ const void * sig = pgpGetSig(dig);
+ int_32 siglen = pgpGetSiglen(dig);
+ int_32 sigtag = pgpGetSigtag(dig);
+ rpmRC res;
+
+ if (dig == NULL || sig == NULL || siglen <= 0) {
+ sprintf(result, _("Verify signature: BAD PARAMETERS\n"));
+ return RPMRC_NOTFOUND;
+ }
+
+ switch (sigtag) {
+ case RPMSIGTAG_SIZE:
+ res = verifySizeSignature(dig, result);
+ break;
+ case RPMSIGTAG_MD5:
+ res = verifyMD5Signature(dig, result, dig->md5ctx);
+ break;
+ case RPMSIGTAG_SHA1:
+ res = verifySHA1Signature(dig, result, dig->hdrsha1ctx);
+ break;
+ case RPMSIGTAG_RSA:
+ res = verifyRSASignature(dig, result, dig->hdrmd5ctx);
+ break;
+#if defined(SUPPORT_RPMV3_VERIFY_RSA)
+ case RPMSIGTAG_PGP5: /* XXX legacy */
+ case RPMSIGTAG_PGP:
+ res = verifyRSASignature(dig, result,
+ ((dig->signature.hash_algo == PGPHASHALGO_MD5)
+ ? dig->md5ctx : dig->sha1ctx));
+ break;
+#endif
+ case RPMSIGTAG_DSA:
+ res = verifyDSASignature(dig, result, dig->hdrsha1ctx);
+ break;
+#if defined(SUPPORT_RPMV3_VERIFY_DSA)
+ case RPMSIGTAG_GPG:
+ res = verifyDSASignature(dig, result, dig->sha1ctx);
+ break;
+#endif
+#if defined(SUPPORT_RPMV3_BROKEN)
+ case RPMSIGTAG_LEMD5_1:
+ case RPMSIGTAG_LEMD5_2:
+ sprintf(result, _("Broken MD5 digest: UNSUPPORTED\n"));
+ res = RPMRC_NOTFOUND;
+ break;
+#endif
+ default:
+ sprintf(result, _("Signature: UNKNOWN (%d)\n"), sigtag);
+ res = RPMRC_NOTFOUND;
+ break;
+ }
+ return res;
+}
@@ .
patch -p0 <<'@@ .'
Index: rpm/rpmdb/signature.h
============================================================================
$ cvs diff -u -r0 -r1.1 signature.h
--- /dev/null 2007-10-01 00:33:00 +0200
+++ signature.h 2007-10-01 00:38:31 +0200
@@ -0,0 +1,85 @@
+#ifndef H_SIGNATURE
+#define H_SIGNATURE
+
+/** \ingroup signature
+ * \file lib/signature.h
+ * Generate and verify rpm package signatures.
+ */
+
+#include <header.h>
+
+/** \ingroup signature
+ * Identify PGP versions.
+ * @note Greater than 0 is a valid PGP version.
+ */
+typedef enum pgpVersion_e {
+ PGP_NOTDETECTED = -1,
+ PGP_UNKNOWN = 0,
+ PGP_2 = 2,
+ PGP_5 = 5
+} pgpVersion;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Return file handle for a temporaray file.
+ * A unique temporaray file path will be generated using
+ * rpmGenPath(prefix, "%{_tmppath}/", "rpm-tmp.XXXXX")
+ * where "XXXXXX" is filled in using rand(3). The file is opened, and
+ * the link count and (dev,ino) location are verified after opening.
+ * The file name and the open file handle are returned.
+ *
+ * @param prefix leading part of temp file path
+ * @retval *fnptr temp file name (or NULL)
+ * @retval *fdptr temp file handle
+ * @return 0 on success
+ */
+int rpmTempFile(/*@null@*/ const char * prefix,
+ /*@null@*/ /*@out@*/ const char ** fnptr,
+ /*@out@*/ void * fdptr)
+ /*@globals rpmGlobalMacroContext, h_errno,
+ fileSystem, internalState @*/
+ /*@modifies *fnptr, *fdptr, rpmGlobalMacroContext,
+ fileSystem, internalState @*/;
+
+/** \ingroup signature
+ * Generate signature(s) from a header+payload file, save in signature header.
+ * @param sigh signature header
+ * @param file header+payload file name
+ * @param sigTag type of signature(s) to add
+ * @param passPhrase private key pass phrase
+ * @return 0 on success, -1 on failure
+ */
+int rpmAddSignature(Header sigh, const char * file,
+ int_32 sigTag, /*@null@*/ const char * passPhrase)
+ /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
+ /*@modifies sigh, sigTag, rpmGlobalMacroContext, fileSystem, internalState @*/;
+
+/**
+ * Check for valid pass phrase by invoking a helper.
+ * @param passPhrase pass phrase
+ * @return 0 on valid, 1 on invalid
+ */
+int rpmCheckPassPhrase(const char * passPhrase)
+ /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
+ /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/;
+
+/** \ingroup signature
+ * Verify a signature from a package.
+ *
+ * @param _dig container
+ * @retval result detailed text result of signature verification
+ * @return result of signature verification
+ */
+rpmRC rpmVerifySignature(void * _dig, /*@out@*/ char * result)
+ /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
+ /*@modifies _dig, *result, rpmGlobalMacroContext,
+ fileSystem, internalState @*/;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* H_SIGNATURE */
@@ .
Received on Mon Oct 1 00:38:31 2007