diff -uNr rpm2html-1.5.orig/Makefile.in rpm2html-1.5/Makefile.in
--- rpm2html-1.5.orig/Makefile.in Sun Sep 24 16:34:03 2000
+++ rpm2html-1.5/Makefile.in Sun Nov 5 18:27:16 2000
@@ -5,8 +5,9 @@
#CC = insure
SQL_FLAGS=@SQL_FLAGS@
+GPG_FLAGS=@GPG_FLAGS@
-CFLAGS = @CFLAGS@ $(SQL_FLAGS) -Wall
+CFLAGS = @CFLAGS@ $(SQL_FLAGS) $(GPG_FLAGS) -Wall
#CFLAGS = -Wall -g -DDEBUG
#CFLAGS = -Wall -O6
diff -uNr rpm2html-1.5.orig/configure.in rpm2html-1.5/configure.in
--- rpm2html-1.5.orig/configure.in Mon Aug 21 20:35:48 2000
+++ rpm2html-1.5/configure.in Sun Nov 5 18:27:16 2000
@@ -132,4 +132,33 @@
AC_SUBST(SQL_PROGS)
AC_SUBST(SQL_OBJ)
+dnl
+dnl Do we plug in the gpg?
+dnl
+
+GPG_FLAGS=
+GPG_PROG=
+AC_ARG_WITH(gpg, [ --with-gpg Add the GPG support (off)])
+if test "x$with_gpg" != "x" ; then
+ if test "$with_gpg" = "yes" ; then
+ AC_PATH_PROG(GPG_PROG, gpg, /usr/bin/gpg)
+ else
+ AC_PATH_PROG(GPG_PROG, gpg, "$with_gpg")
+ fi
+
+ dnl for now, signature resolving code is implemented only with librpmio
+ dnl so without librpmio it wont work
+ AC_CHECK_LIB(rpmio, Fopen,
+ [LIBS="-lrpmio $LIBS";
+ AC_DEFINE_UNQUOTED(USE_RPMIO, 1)
+ AC_SUBST(USE_RPMIO)
+ ],
+ AC_MSG_ERROR(*** librpmio not found, use --without-gpg))
+
+ echo Enabling GPG support
+ GPG_FLAGS="-DWITH_GPG -DGPG_PROG=\\\"$GPG_PROG\\\""
+fi
+AC_SUBST(GPG_FLAGS)
+AC_SUBST(GPG_PROG)
+
AC_OUTPUT(Makefile)
diff -uNr rpm2html-1.5.orig/html.c rpm2html-1.5/html.c
--- rpm2html-1.5.orig/html.c Sun Sep 24 16:14:39 2000
+++ rpm2html-1.5/html.c Sun Nov 5 18:27:16 2000
@@ -22,6 +22,8 @@
#include
#include
+#include
+
#include "rpm2html.h"
#include "rpmdata.h"
#include "html.h"
@@ -359,13 +361,91 @@
}
/*
+ * Generates signature info (extended ASCII charset)
+ * The string returned is a shared location.
+ */
+#define X(_x) (unsigned)((_x) & 0xff)
+
+static unsigned char *sigInfoMD5 = "MD5: ";
+#if defined(WITH_GPG)
+static unsigned char *sigInfoGPG = "GPG:\n";
+static unsigned char *sigInfoPGP = "PGP:\n";
+#else
+static unsigned char *sigInfoGPG = "GPG";
+static unsigned char *sigInfoPGP = "PGP";
+#endif
+static unsigned char *sigInfoU = "unknown";
+
+static unsigned char *sbuffer = NULL;
+static int sbuffer_size = 2000;
+static unsigned char *sbuffer2 = NULL;
+static int sbuffer2_size = 3;
+char *convertSIG(rpmSigPtr sig) {
+ int n1;
+ unsigned char *md5sum = sig->sig;
+
+ if (sbuffer == NULL) {
+ sbuffer = (char *) debugMalloc(sbuffer_size * sizeof(char));
+ if (sbuffer == NULL) {
+ perror("debugMalloc failed");
+ exit(1);
+ }
+ }
+ if (sbuffer2 == NULL) {
+ sbuffer2 = (char *) debugMalloc(sbuffer2_size * sizeof(char));
+ if (sbuffer2 == NULL) {
+ perror("debugMalloc failed");
+ exit(1);
+ }
+ }
+
+ switch(sig->tag) {
+ case RPMSIGTAG_MD5:
+ strncpy(sbuffer, sigInfoMD5, sbuffer_size);
+ for(n1 = 0; n1 < sig->size; n1++) {
+ snprintf(sbuffer2, sbuffer2_size, "%02x", X(md5sum[n1]));
+ strncat(sbuffer, sbuffer2, sbuffer_size);
+ }
+ return(sbuffer);
+ case RPMSIGTAG_GPG:
+ #if defined(WITH_GPG)
+ strncpy(sbuffer, sigInfoGPG, sbuffer_size);
+ if (sig->resolve != NULL)
+ strncat(sbuffer, sig->resolve, sbuffer_size);
+ return(sbuffer);
+ #else
+ return(sigInfoGPG);
+ #endif
+ case RPMSIGTAG_PGP:
+ #if defined(WITH_GPG)
+ strncpy(sbuffer, sigInfoPGP, sbuffer_size);
+ if (sig->resolve != NULL)
+ strncat(sbuffer, sig->resolve, sbuffer_size);
+ return(sbuffer);
+ #else
+ return(sigInfoPGP);
+ #endif
+ default:
+ return(sigInfoU);
+ }
+}
+
+/*
* Cleanup the global varibales of this module
*/
void htmlCleanup(void) {
if (buffer != NULL)
debugFree(buffer);
+ if (sbuffer != NULL)
+ debugFree(buffer);
+ if (sbuffer2 != NULL)
+ debugFree(buffer);
buffer = NULL;
buffer_size = 2000;
+ sbuffer = NULL;
+ sbuffer_size = 2000;
+ sbuffer2 = NULL;
+ sbuffer2_size = 3;
}
/*
@@ -1274,6 +1354,12 @@
fprintf(html, "%s
\n",
localizedStrings[LANG_COPYRIGHT]);
fprintf(html, "%s\n
\n", convertHTML(rpm->extra->copyright));
+ }
+ if (rpm->extra->sigs != NULL) {
+ fprintf(html, "%s
\n",
+ localizedStrings[LANG_SIGNATURES]);
+ for(i = 0; i < rpm->extra->nb_sigs; i++)
+ fprintf(html, "%s\n
\n", convertHTML(convertSIG(rpm->extra->sigs[i])));
}
if (rpm->extra->changelog) {
fprintf(html, "%s
\n",
diff -uNr rpm2html-1.5.orig/language.c rpm2html-1.5/language.c
--- rpm2html-1.5.orig/language.c Sun Sep 24 16:14:40 2000
+++ rpm2html-1.5/language.c Sun Nov 5 18:27:06 2000
@@ -127,7 +127,8 @@
"\n"
+ \n",
+ "Signatures"
};
#define NB_STRINGS (sizeof(localizedStrings)/sizeof(char *))
diff -uNr rpm2html-1.5.orig/language.h rpm2html-1.5/language.h
--- rpm2html-1.5.orig/language.h Sat Sep 9 21:29:03 2000
+++ rpm2html-1.5/language.h Sun Nov 5 18:27:06 2000
@@ -91,6 +91,7 @@
#define LANG_TREE_HTML 79
#define LANG_BROWSE_TREE 80
#define LANG_SEARCH_FORM 81
+#define LANG_SIGNATURES 82
/*
* Array containing the localized language strings.
diff -uNr rpm2html-1.5.orig/rpmdata.h rpm2html-1.5/rpmdata.h
--- rpm2html-1.5.orig/rpmdata.h Sat Sep 9 14:06:59 2000
+++ rpm2html-1.5/rpmdata.h Sun Nov 5 18:27:16 2000
@@ -148,6 +148,9 @@
int max_requires; /* #of resources slot allocated */
struct rpm_resource **requires;/* list of them */
char *filelist; /* the filelist */
+ int nb_sigs; /* #of signatures required */
+ int max_sigs; /* #of signatures slot allocated */
+ struct rpm_sig **sigs; /* list of them */
} rpmExtraData, *rpmExtraDataPtr;
/*
@@ -165,6 +168,18 @@
struct rpm_data **provider; /* list of them */
} rpmRess, *rpmRessPtr;
+/*
+ * structure associated with signature
+ */
+typedef struct rpm_sig {
+ int size; /* size of signature */
+ int tag; /* signature tag */
+ int type; /* signature type */
+ int *sig; /* signature */
+ #if defined(WITH_GPG)
+ char *resolve; /* resolved signature */
+ #endif
+} rpmSig, *rpmSigPtr;
/*
* Variables.
diff -uNr rpm2html-1.5.orig/rpmopen.c rpm2html-1.5/rpmopen.c
--- rpm2html-1.5.orig/rpmopen.c Sat Sep 9 21:29:03 2000
+++ rpm2html-1.5/rpmopen.c Sun Nov 5 18:27:16 2000
@@ -3,7 +3,7 @@
*
* See Copyright for the status of this software.
*
- * $Id: rpmopen.c,v 1.82 2000/09/09 19:29:02 veillard Exp $
+ * $Id: rpmopen.c,v 1.84 2000/10/25 08:47:19 daniel Exp $
*/
#include
@@ -24,6 +24,16 @@
#include
#include /* Added by A. Gibert */
+//#include - not included in rpm-devel package
+// XXX hack - I hope that readLead IS in librpm.o even when .h is missing
+int readLead(FD_t fd, /*@out@*/struct rpmlead *lead);
+//#include - not included in rpm-devel package
+// XXX hack - I hope that int rpmReadSignature IS in librpm.o even when .h is missing
+int rpmReadSignature(FD_t fd, /*@out@*/ Header *header, short sig_type);
+
+#if defined(WITH_GPG)
+#include
+#endif
#include "rpm2html.h"
#include "rpmdata.h"
@@ -57,6 +67,7 @@
void rpmFreeExtraData(rpmDataPtr rpm) {
rpmExtraDataPtr extra;
+ int n1;
if ((rpm == NULL) || (rpm->extra == NULL)) return;
extra = rpm->extra;
@@ -69,6 +80,17 @@
if (extra->resources != NULL) debugFree(extra->resources);
if (extra->requires != NULL) debugFree(extra->requires);
if (extra->filelist != NULL) debugFree(extra->filelist);
+ if (extra->sigs != NULL) {
+ for (n1 = 0; n1 < extra->nb_sigs; n1++)
+ if (extra->sigs[n1] != NULL) {
+ if (extra->sigs[n1]->sig != NULL)
+ debugFree(extra->sigs[n1]->sig);
+ if (extra->sigs[n1]->resolve != NULL)
+ debugFree(extra->sigs[n1]->resolve);
+ debugFree(extra->sigs[n1]);
+ }
+ debugFree(extra->sigs);
+ }
debugFree(extra);
}
@@ -173,6 +195,115 @@
return(1);
}
+#if defined(WITH_GPG)
+/*
+ * rpmResolveGPGPSignatures : resolve GPG and PGP signatures found in package
+ * code based on rpm-4.0-0.45
+ */
+void rpmResolveGPGPSignature(const char *nameRpm, const char *sigtarget,
+ const char *sigfile, rpmDataPtr rpm, int sign) {
+ int pid, status, outpipe[2];
+ FILE *file;
+ int rsize = 128, crsize;
+ unsigned char buf[8192];
+
+ /* Now run GPG */
+ outpipe[0] = outpipe[1] = 0;
+ pipe(outpipe);
+
+ if (!(pid = fork())) {
+ close(outpipe[0]);
+ /* gpg version 0.9 sends its output to stderr. */
+ dup2(outpipe[1], STDERR_FILENO);
+
+ execlp(GPG_PROG, GPG_PROG,
+ "--batch", "--no-verbose",
+ "--verify", sigfile, sigtarget,
+ NULL);
+ fprintf(stderr, "%s exec failed!\n", GPG_PROG);
+ exit(1);
+ }
+
+ close(outpipe[1]);
+ file = fdopen(outpipe[0], "r");
+ rpm->extra->sigs[sign]->resolve = debugMalloc(sizeof(char) * rsize);
+ rpm->extra->sigs[sign]->resolve[0] = '\0';
+ while (fgets(buf, 1024, file)) {
+ crsize = strlen(buf) + strlen(rpm->extra->sigs[sign]->resolve);
+ if (crsize >= rsize) {
+ rsize = crsize * 2;
+ rpm->extra->sigs[sign]->resolve = debugRealloc(rpm->extra->sigs[sign]->resolve,
+ sizeof(char) * rsize);
+ if (rpm->extra->sigs[sign]->resolve == NULL) {
+ fprintf(stderr, "cannot re-allocate %d bytes: %s\n",
+ rsize, strerror(errno));
+ exit (1);
+ }
+ }
+
+ strcat(rpm->extra->sigs[sign]->resolve, buf);
+ }
+ fclose(file);
+
+ (void)waitpid(pid, &status, 0);
+}
+
+/*
+ * rpmResolveMD5Signatures : resolve MD5 signatures found in package
+ * code based on rpm-4.0-0.45
+ * for now, we are not checking whether MD5 sums are OK
+ */
+/*void rpmResolveMD5Signature(const char *nameRpm, const char *sigtarget,
+ const char *sigfile, rpmDataPtr rpm, int sign) {
+}*/
+
+/*
+ * rpmResolveSignatures : resolve signatures found in package
+ * code based on rpm-4.0-0.45
+ */
+void rpmResolveSignatures(const char *path, const char *nameRpm,
+ const char *sigtarget, rpmDataPtr rpm) {
+ int sign = 0;
+
+ if (rpm == NULL || rpm->extra->nb_sigs == 0 || sigtarget == NULL) return;
+
+ for (sign = 0; sign < rpm->extra->nb_sigs; sign++) {
+ FD_t sfd;
+ char *sigfile = NULL;
+
+ if (rpm->extra->sigs[sign]->tag != RPMSIGTAG_PGP
+ && rpm->extra->sigs[sign]->tag != RPMSIGTAG_GPG)
+ continue;
+
+ /* Write out the signature */
+ sigfile = debugMalloc(30);
+ strcpy(sigfile, "/tmp/rpm2html.sig.XXXXXX");
+ sigfile = mktemp(sigfile);
+ sfd = Fopen(sigfile, "w.fdio");
+ (void)Fwrite(rpm->extra->sigs[sign]->sig, sizeof(char),
+ rpm->extra->sigs[sign]->size, sfd);
+ Fclose(sfd);
+
+ switch(rpm->extra->sigs[sign]->tag) {
+ case RPMSIGTAG_PGP:
+ case RPMSIGTAG_GPG:
+ rpmResolveGPGPSignature(nameRpm, sigtarget, sigfile, rpm, sign);
+ break;
+ /*case RPMSIGTAG_MD5:
+ rpmResolveMD5Signature(nameRpm, sigtarget, sigfile, rpm, sign);
+ break;*/
+ default:
+ break;
+ }
+
+ if (sigfile != NULL) {
+ unlink(sigfile);
+ debugFree(sigfile);
+ }
+ }
+}
+#endif
+
/*
* rpmAnalyze : analyze an RPM record, read and parse the header and
* fill the informations in the database.
@@ -184,8 +315,9 @@
static char *buffer = NULL;
static int buffer_size = 50 * 1024 * sizeof(char);
-rpmDataPtr rpmAnalyze(char *path, char *nameRpm, Header h, rpmDirPtr dir,
- rpmSubdirPtr tree, time_t stamp, int isSource) {
+rpmDataPtr rpmAnalyze(char *path, char *nameRpm, const char *sigtarget,
+ Header h, Header s, rpmDirPtr dir, rpmSubdirPtr tree,
+ time_t stamp, int isSource) {
int installed = dir->installbase;
char * name = NULL, * version = NULL, * release = NULL;
int_32 count, type;
@@ -196,6 +328,7 @@
#ifdef WITH_SQL
int id;
#endif
+ HeaderIterator sIter;
if (buffer == NULL) {
buffer = (char *) debugMalloc(buffer_size);
@@ -510,6 +643,46 @@
else rpm->vendor = debugStrdup(localizedStrings[LANG_UNKNOWN]);
}
+ if (s == NULL)
+ rpm->extra->sigs = NULL;
+ else {
+ int tag, type;
+
+ rpm->extra->max_sigs = 1;
+ rpm->extra->sigs = (rpmSigPtr *) debugMalloc(sizeof(rpmSigPtr) *
+ rpm->extra->max_sigs);
+ rpm->extra->sigs[0] = NULL;
+ rpm->extra->nb_sigs = 0;
+
+ for (sIter = headerInitIterator(s);
+ headerNextIterator(sIter, &tag, &type, &p, &count);
+ )
+ {
+ if ((tag != RPMSIGTAG_MD5) && (tag != RPMSIGTAG_PGP) && (tag != RPMSIGTAG_GPG))
+ continue;
+ if (rpm->extra->nb_sigs >= rpm->extra->max_sigs) {
+ rpm->extra->max_sigs *= 2;
+ rpm->extra->sigs = (rpmSigPtr *) debugRealloc(rpm->extra->sigs,
+ sizeof(rpmSigPtr) * rpm->extra->max_sigs);
+ if (rpm->extra->sigs == NULL) {
+ fprintf(stderr, "cannot re-allocate %d bytes: %s\n",
+ rpm->extra->max_sigs, strerror(errno));
+ exit(1);
+ }
+ }
+
+ rpm->extra->sigs[rpm->extra->nb_sigs] = (rpmSigPtr) debugMalloc(sizeof(rpmSig));
+ rpm->extra->sigs[rpm->extra->nb_sigs]->tag = tag;
+ rpm->extra->sigs[rpm->extra->nb_sigs]->type = type;
+ rpm->extra->sigs[rpm->extra->nb_sigs]->size = count;
+ rpm->extra->sigs[rpm->extra->nb_sigs]->sig = debugMalloc(count);
+ memcpy(rpm->extra->sigs[rpm->extra->nb_sigs]->sig, p, count);
+ rpm->extra->sigs[rpm->extra->nb_sigs]->resolve = NULL;
+ rpm->extra->nb_sigs++;
+ ENTRY_CLEANUP(p);
+ }
+ }
+
rpm->filename = debugStrdup(nameRpm);
/* package-xxx.rpm provides at least the resource "package" */
@@ -628,6 +801,10 @@
}
ENTRY_CLEANUP(p);
+ #ifdef WITH_GPG
+ rpmResolveSignatures(path, nameRpm, sigtarget, rpm);
+ #endif WITH_GPG
+
#ifdef WITH_SQL
id = sql_add_package(path, rpm->name, rpm->version, rpm->release,
rpm->arch, dir->no, rpm->url, rpm->extra->srcrpm,
@@ -719,9 +896,17 @@
#endif
int rc;
Header h = NULL;
+ Header s = NULL;
+ struct rpmlead lead;
int isSource;
char buffer[500];
struct stat buf;
+#if defined(WITH_GPG)
+ FD_t ofd = NULL;
+ char *sigtarget = NULL;
+ ssize_t count;
+ unsigned char stbuffer[8192];
+#endif
/* open the file for reading */
if (tree->htmlpath[0] != '\0')
@@ -778,16 +963,107 @@
return(NULL);
}
- cur = rpmAnalyze(buffer, nameRpm, h, dir, tree, buf.st_mtime, isSource);
- /* free the header and close the descriptor */
- headerFree(h);
+ /* close the descriptor */
+#if defined(USE_RPMIO)
+ Fclose(fd);
+#else
+ fdClose(fd);
+#endif
+
+ /* XXX I do not know whether it is necessary to open the file twice */
+ /* open the file for reading */
+#if defined(USE_RPMIO)
+ fd = Fopen(buffer, "r.fdio");
+ if (fd == NULL || Ferror(fd)) {
+ fprintf(stderr, "Fopen of %s failed: %s\n", buffer,
+ Fstrerror(fd));
+ return(NULL);
+ }
+#else
+ if ((fd = fdOpen(buffer, O_RDONLY, 0)) < 0) {
+ fprintf(stderr, "open of %s failed: %s\n", buffer,
+ strerror(errno));
+ return(NULL);
+ }
+#endif
+
+ /* read the RPM signature */
+ if (readLead(fd, &lead)) {
+ fprintf(stderr, "readLead failed\n");
+ fdClose(fd);
+ return(NULL);
+ }
+ switch (lead.major) {
+ case 1:
+ fprintf(stderr, "no signature available (v1.0 RPM) in %s\n", nameRpm);
+ break;
+ default:
+ if (rpmReadSignature(fd, &s, lead.signature_type)) {
+ fprintf(stderr, "rpmReadSignature failed\n");
+ fdClose(fd);
+ return(NULL);
+ }
+ if (!s) {
+ fprintf(stderr, "no signature available in %s\n", nameRpm);
+ fdClose(fd);
+ return(NULL);
+ }
+#if defined(WITH_GPG)
+ /* open temp file for writing */
+ sigtarget = debugMalloc(30);
+ strcpy(sigtarget, "/tmp/rpm2html.date.XXXXXX");
+ sigtarget = mktemp(sigtarget);
+ ofd = Fopen(sigtarget, "w.ufdio");
+ if (ofd == NULL || Ferror(ofd)) {
+ fprintf(stderr, "Fopen of %s failed: %s\n", sigtarget,
+ Fstrerror(ofd));
+ debugFree(sigtarget);
+ sigtarget = NULL;
+ }
+
+ /* write the header and archive to a temp file */
+ while ((count = Fread(stbuffer, sizeof(stbuffer[0]), sizeof(stbuffer), fd)) > 0) {
+ if (Fwrite(stbuffer, sizeof(stbuffer[0]), count, ofd) < 0) {
+ fprintf(stderr, "%s: Fwrite failed: %s\n", sigtarget,
+ Fstrerror(ofd));
+ debugFree(sigtarget);
+ sigtarget = NULL;
+ }
+ }
+ if (count < 0) {
+ fprintf(stderr, "%s: Fread failed: %s\n", buffer, Fstrerror(fd));
+ debugFree(sigtarget);
+ sigtarget = NULL;
+ }
+
+ Fclose(ofd);
+#endif
+ break;
+ }
+
+ /* close the descriptor */
#if defined(USE_RPMIO)
Fclose(fd);
#else
fdClose(fd);
#endif
+#if defined(WITH_GPG)
+ cur = rpmAnalyze(buffer, nameRpm, sigtarget, h, s, dir, tree, buf.st_mtime, isSource);
+#else
+ cur = rpmAnalyze(buffer, nameRpm, NULL, h, s, dir, tree, buf.st_mtime, isSource);
+#endif
+
+ /* free the header */
+ headerFree(h);
+ headerFree(s);
+
+ if (sigtarget) {
+ unlink(sigtarget);
+ debugFree(sigtarget);
+ }
+
return(cur);
}
@@ -995,7 +1271,7 @@
{ rpmdbMatchIterator mi;
mi = rpmdbInitIterator(db, RPMDBI_PACKAGES, NULL, 0);
while ((h = rpmdbNextIterator(mi)) != NULL) {
- cur = rpmAnalyze(NULL, NULL, h, dir, NULL, 0, 0);
+ cur = rpmAnalyze(NULL, NULL, NULL, h, NULL, dir, NULL, 0, 0);
if (cur != NULL) ret = rpmAddList(ret, cur);
}
rpmdbFreeIterator(mi);