Index: Makefile.in =================================================================== RCS file: /network/prog/CVS/hany/rpm2html/Makefile.in,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- Makefile.in 2000/11/05 11:04:34 1.1.1.1 +++ Makefile.in 2000/11/05 17:04:35 1.2 @@ -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 Index: configure.in =================================================================== RCS file: /network/prog/CVS/hany/rpm2html/configure.in,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 configure.in --- configure.in 2000/11/05 11:04:34 1.1.1.1 +++ configure.in 2000/11/05 17:57:24 @@ -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) Index: html.c =================================================================== RCS file: /network/prog/CVS/hany/rpm2html/html.c,v retrieving revision 1.2 diff -u -r1.2 html.c --- html.c 2000/11/05 11:07:59 1.2 +++ html.c 2000/11/05 17:55:56 @@ -367,8 +367,13 @@ #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; @@ -403,9 +408,23 @@ } 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); } Index: rpmdata.h =================================================================== RCS file: /network/prog/CVS/hany/rpm2html/rpmdata.h,v retrieving revision 1.2 diff -u -r1.2 rpmdata.h --- rpmdata.h 2000/11/05 11:08:00 1.2 +++ rpmdata.h 2000/11/05 17:55:51 @@ -176,6 +176,9 @@ int tag; /* signature tag */ int type; /* signature type */ int *sig; /* signature */ + #if defined(WITH_GPG) + char *resolve; /* resolved signature */ + #endif } rpmSig, *rpmSigPtr; /* Index: rpmopen.c =================================================================== RCS file: /network/prog/CVS/hany/rpm2html/rpmopen.c,v retrieving revision 1.3 diff -u -r1.3 rpmopen.c --- rpmopen.c 2000/11/05 11:12:42 1.3 +++ rpmopen.c 2000/11/05 18:19:31 @@ -31,6 +31,10 @@ // 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" #include "html.h" @@ -78,8 +82,13 @@ 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] != 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); @@ -186,7 +195,116 @@ 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. */ @@ -197,9 +315,9 @@ static char *buffer = NULL; static int buffer_size = 50 * 1024 * sizeof(char); -rpmDataPtr rpmAnalyze(char *path, char *nameRpm, Header h, Header s, - 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; @@ -557,7 +675,9 @@ 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 = debugRealloc(p, 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); } @@ -681,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, @@ -777,6 +901,12 @@ 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') @@ -843,11 +973,6 @@ /* XXX I do not know whether it is necessary to open the file twice */ /* open the file for reading */ - if (tree->htmlpath[0] != '\0') - snprintf(buffer, sizeof(buffer), "%s/%s/%s", dir->rpmdir, tree->rpmpath, nameRpm); - else - snprintf(buffer, sizeof(buffer), "%s/%s", dir->rpmdir, nameRpm); - #if defined(USE_RPMIO) fd = Fopen(buffer, "r.fdio"); if (fd == NULL || Ferror(fd)) { @@ -884,6 +1009,36 @@ 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; } @@ -894,12 +1049,21 @@ fdClose(fd); #endif - cur = rpmAnalyze(buffer, nameRpm, h, s, dir, tree, buf.st_mtime, isSource); +#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); } @@ -1107,7 +1271,7 @@ { rpmdbMatchIterator mi; mi = rpmdbInitIterator(db, RPMDBI_PACKAGES, NULL, 0); while ((h = rpmdbNextIterator(mi)) != NULL) { - cur = rpmAnalyze(NULL, NULL, h, NULL, dir, NULL, 0, 0); + cur = rpmAnalyze(NULL, NULL, NULL, h, NULL, dir, NULL, 0, 0); if (cur != NULL) ret = rpmAddList(ret, cur); } rpmdbFreeIterator(mi);