Hi,

attached my attempt to make my previous patches a bit nicer, it
applies on top of the previous set and adds a "struct debsig_ctx" to
avoid passing three args (originID, deb, deb_fs) to the functions. 

As always, feedback welcome :)

Thanks,
 Michael
>From 6db400f2d938dc967e657d29e483420636d5080d Mon Sep 17 00:00:00 2001
From: Michael Vogt <m...@ubuntu.com>
Date: Wed, 20 Aug 2014 14:13:29 +0200
Subject: [PATCH]  use new "struct debsig_ctx" instead of a global state

---
 Makefile        |  4 +--
 ar-parse.c      | 20 +++++++-------
 debsig-verify.c | 82 ++++++++++++++++++++++++++-------------------------------
 debsig.h        | 15 ++++++++---
 gpg-parse.c     | 16 +++++------
 misc.c          |  4 +--
 6 files changed, 71 insertions(+), 70 deletions(-)

diff --git a/Makefile b/Makefile
index 2dc0256..6a72b72 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 CC = gcc
-CFLAGS = -Wall -Wextra -g -O2
+DS_CFLAGS = -Wall -Wextra -g3 -O2
 
 #TESTING=1
 
@@ -31,7 +31,7 @@ MANPAGES = debsig-verify.1
 all: $(PROGRAM) $(MANPAGES)
 
 $(PROGRAM): $(OBJS)
-	$(CC) $(MK_CFLAGS) $(CFLAGS) $(OBJS) $(MK_LDFLAGS) $(LDFLAGS) -o $@
+	$(CC) $(MK_CFLAGS) $(DS_CFLAGS) $(OBJS) $(MK_LDFLAGS) $(LDFLAGS) -o $@
 
 install: all
 	install -d -m755 $(DESTDIR)/usr/bin
diff --git a/ar-parse.c b/ar-parse.c
index 5ff558a..8138e55 100644
--- a/ar-parse.c
+++ b/ar-parse.c
@@ -39,7 +39,7 @@
  * nothing important is going to be zero length anyway, so we treat it as
  * "non-existant".  */
 off_t
-findMember(const char *deb, const char *name, FILE *deb_fs)
+findMember(const struct debsig_ctx *ds_ctx, const char *name)
 {
     char magic[SARMAG+1];
     struct ar_hdr arh;
@@ -53,12 +53,14 @@ findMember(const char *deb, const char *name, FILE *deb_fs)
     }
 
     /* This shouldn't happen, but... */
-    if (deb_fs == NULL)
+    if (ds_ctx == NULL)
+	ds_fail_printf(DS_FAIL_INTERNAL, "findMember: called while ds_ctx == NULL");
+    if (ds_ctx->deb_fs == NULL)
 	ds_fail_printf(DS_FAIL_INTERNAL, "findMember: called while deb_fs == NULL");
 
-    rewind(deb_fs);
+    rewind(ds_ctx->deb_fs);
 
-    if (!fgets(magic,sizeof(magic),deb_fs))
+    if (!fgets(magic,sizeof(magic), ds_ctx->deb_fs))
 	ds_fail_printf(DS_FAIL_INTERNAL, "findMember: failure to read package (%s)",
 		  strerror(errno));
 
@@ -68,9 +70,9 @@ findMember(const char *deb, const char *name, FILE *deb_fs)
 	return 0;
     }
 
-    while(!feof(deb_fs)) {
-	if (fread(&arh, 1, sizeof(arh),deb_fs) != sizeof(arh)) {
-	    if (ferror(deb_fs))
+    while(!feof(ds_ctx->deb_fs)) {
+	if (fread(&arh, 1, sizeof(arh), ds_ctx->deb_fs) != sizeof(arh)) {
+	    if (ferror(ds_ctx->deb_fs))
 		ds_fail_printf(DS_FAIL_INTERNAL, "findMember: error while parsing archive header (%s)",
 			  strerror(errno));
 	    return 0;
@@ -80,7 +82,7 @@ findMember(const char *deb, const char *name, FILE *deb_fs)
 	    ds_fail_printf(DS_FAIL_INTERNAL, "findMember: archive appears to be corrupt, fmag incorrect");
 
 	dpkg_ar_normalize_name(&arh);
-	mem_len = dpkg_ar_member_get_size(deb, &arh);
+	mem_len = dpkg_ar_member_get_size(ds_ctx->deb, &arh);
 
 	/*
 	 * If all looks well, then we return the length of the member, and
@@ -97,7 +99,7 @@ findMember(const char *deb, const char *name, FILE *deb_fs)
 	    return mem_len;
 
 	/* fseek to the start of the next member, and try again */
-	if (fseek(deb_fs, mem_len + (mem_len & 1), SEEK_CUR) == -1 && ferror(deb_fs))
+	if (fseek(ds_ctx->deb_fs, mem_len + (mem_len & 1), SEEK_CUR) == -1 && ferror(ds_ctx->deb_fs))
 	    ds_fail_printf(DS_FAIL_INTERNAL,
 			   "findMember: error during file seek (%s)", strerror(errno));
     }
diff --git a/debsig-verify.c b/debsig-verify.c
index 069cc7c..f5042a2 100644
--- a/debsig-verify.c
+++ b/debsig-verify.c
@@ -41,7 +41,7 @@ char *ver_magic_member = "debian-binary";
 char *ver_ctrl_members[] = { CTAR(), CTAR(.gz), CTAR(.xz), 0 };
 char *ver_data_members[] = { DTAR(), DTAR(.gz), DTAR(.xz), DTAR(.bz2), DTAR(.lzma), 0 };
 
-static int checkSelRules(const char *originID, struct group *grp, const char *deb, FILE *deb_fs) {
+static int checkSelRules(struct debsig_ctx *ds_ctx, struct group *grp) {
     int opt_count = 0;
     struct match *mtc;
     int len;
@@ -53,8 +53,8 @@ static int checkSelRules(const char *originID, struct group *grp, const char *de
         /* If we have an ID for this match, check to make sure it exists, and
          * matches the signature we are about to check.  */
         if (mtc->id) {
-            char *m_id = getKeyID(originID, mtc);
-            char *d_id = getSigKeyID(deb, mtc->name);
+            char *m_id = getKeyID(ds_ctx->originID, mtc);
+            char *d_id = getSigKeyID(ds_ctx, mtc->name);
             if (m_id == NULL || d_id == NULL || strcmp(m_id, d_id))
                 return 0;
         }
@@ -64,7 +64,7 @@ static int checkSelRules(const char *originID, struct group *grp, const char *de
 	 * specified, don't we?
 	 */
 
-        len = checkSigExist(deb, mtc->name, deb_fs);
+        len = checkSigExist(ds_ctx, mtc->name);
 
         /* If the member exists and we reject it, fail now. Also, if it
          * doesn't exist, and we require it, fail as well. */
@@ -104,7 +104,7 @@ passthrough(FILE *in, FILE *out, off_t len)
     return len;
 }
 
-static int verifyGroupRules(const char *originID, struct group *grp, const char *deb, FILE *deb_fs) {
+static int verifyGroupRules(struct debsig_ctx *ds_ctx, struct group *grp) {
     FILE *fp;
     char tmp_sig[32] = {'\0'}, tmp_data[32] = {'\0'};
     int opt_count = 0, t, i, fd;
@@ -131,23 +131,23 @@ static int verifyGroupRules(const char *originID, struct group *grp, const char
 
     /* Now, let's find all the members we need to check and cat them into a
      * single temp file. This is what we pass to gpg.  */
-    if (!(len = findMember(deb, ver_magic_member, deb_fs)))
+    if (!(len = findMember(ds_ctx, ver_magic_member)))
         goto fail_and_close;
-    len = passthrough(deb_fs, fp, len);
+    len = passthrough(ds_ctx->deb_fs, fp, len);
 
     for (i = 0; ver_ctrl_members[i]; i++) {
-       if (!(len = findMember(deb, ver_ctrl_members[i], deb_fs)))
+       if (!(len = findMember(ds_ctx, ver_ctrl_members[i])))
 	    continue;
-	len = passthrough(deb_fs, fp, len);
+	len = passthrough(ds_ctx->deb_fs, fp, len);
 	break;
     }
     if (!ver_ctrl_members[i])
 	goto fail_and_close;
 
     for (i = 0; ver_data_members[i]; i++) {
-        if (!(len = findMember(deb, ver_data_members[i], deb_fs)))
+        if (!(len = findMember(ds_ctx, ver_data_members[i])))
 	    continue;
-	len = passthrough(deb_fs, fp, len);
+	len = passthrough(ds_ctx->deb_fs, fp, len);
 	break;
     }
     if (!ver_data_members[i])
@@ -163,14 +163,14 @@ static int verifyGroupRules(const char *originID, struct group *grp, const char
 	/* If we have an ID for this match, check to make sure it exists, and
 	 * matches the signature we are about to check.  */
 	if (mtc->id) {
-            char *m_id = getKeyID(originID, mtc);
-	    char *d_id = getSigKeyID(deb, mtc->name);
+            char *m_id = getKeyID(ds_ctx->originID, mtc);
+	    char *d_id = getSigKeyID(ds_ctx, mtc->name);
 	    if (m_id == NULL || d_id == NULL || strcmp(m_id, d_id))
 		goto fail_and_close;
 	}
 
 	/* This will also position deb_fs to the start of the member */
-	len = checkSigExist(deb, mtc->name, deb_fs);
+	len = checkSigExist(ds_ctx, mtc->name);
 
 	/* If the member exists and we reject it, die now. Also, if it
 	 * doesn't exist, and we require it, die as well. */
@@ -190,11 +190,11 @@ static int verifyGroupRules(const char *originID, struct group *grp, const char
 	    goto fail_and_close;
 	}
 
-	len = passthrough(deb_fs, fp, len);
+	len = passthrough(ds_ctx->deb_fs, fp, len);
 	fclose(fp);
 
 	/* Now, let's check with gpg on this one */
-	t = gpgVerify(originID, tmp_data, mtc, tmp_sig);
+	t = gpgVerify(ds_ctx->originID, tmp_data, mtc, tmp_sig);
 
 	fd = -1;
 	unlink(tmp_sig);
@@ -229,41 +229,36 @@ fail_and_close:
     return 0;
 }
 
-static int checkIsDeb(const char *deb) {
-    int i, res = 0;
+static int checkIsDeb(struct debsig_ctx *ds_ctx) {
+    int i;
     const char *member;
 
-    FILE *deb_fs = fopen(deb, "r");
-
-    if (!findMember(deb, ver_magic_member, deb_fs)) {
+    if (!findMember(ds_ctx, ver_magic_member)) {
        ds_printf(DS_LEV_VER, "Missing archive magic member %s", ver_magic_member);
-       goto out;
+       return 0;
     }
 
     for (i = 0; (member = ver_ctrl_members[i]); i++)
-        if (findMember(deb, member, deb_fs))
+        if (findMember(ds_ctx, member))
             break;
     if (!member) {
         ds_printf(DS_LEV_VER, "Missing archive control member, checked:");
         for (i = 0; (member = ver_ctrl_members[i]); i++)
             ds_printf(DS_LEV_VER, "    %s", member);
-        goto out;
+        return 0;
     }
 
     for (i = 0; (member = ver_data_members[i]); i++)
-        if (findMember(deb, member, deb_fs))
+        if (findMember(ds_ctx, member))
             break;
     if (!member) {
         ds_printf(DS_LEV_VER, "Missing archive data member, checked:");
         for (i = 0; (member = ver_data_members[i]); i++)
             ds_printf(DS_LEV_VER, "    %s", member);
-        goto out;
+        return 0;
     }
-    res = 1;
 
- out:
-    fclose(deb_fs);
-    return res;
+    return 1;
 }
 
 static void outputVersion(void) {
@@ -314,7 +309,6 @@ int main(int argc, char *argv[]) {
     struct dirent *pd_ent;
     struct group *grp;
     int i, list_only = 0;
-    FILE *deb_fs;
 
     dpkg_set_progname(argv[0]);
 
@@ -364,25 +358,25 @@ int main(int argc, char *argv[]) {
     if (i + 1 != argc) /* There should only be one arg left */
 	outputUsage();
 
-    const char *deb = argv[i];
+    struct debsig_ctx ds_ctx;
+    ds_ctx.deb = argv[i];
 
-    if ((deb_fs = fopen(deb, "r")) == NULL)
-	ds_fail_printf(DS_FAIL_INTERNAL, "could not open %s (%s)", deb, strerror(errno));
+    if ((ds_ctx.deb_fs = fopen(ds_ctx.deb, "r")) == NULL)
+	ds_fail_printf(DS_FAIL_INTERNAL, "could not open %s (%s)", ds_ctx.deb, strerror(errno));
 
     if (!list_only)
-	ds_printf(DS_LEV_VER, "Starting verification for: %s", deb);
+	ds_printf(DS_LEV_VER, "Starting verification for: %s", ds_ctx.deb);
 
-    if (!checkIsDeb(deb))
-	ds_fail_printf(DS_FAIL_INTERNAL, "%s does not appear to be a deb format package", deb);
+    if (!checkIsDeb(&ds_ctx))
+	ds_fail_printf(DS_FAIL_INTERNAL, "%s does not appear to be a deb format package", ds_ctx.deb);
 
-    if ((tmpID = getSigKeyID(deb, "origin")) == NULL)
+    if ((tmpID = getSigKeyID(&ds_ctx, "origin")) == NULL)
 	ds_fail_printf(DS_FAIL_NOSIGS, "Origin Signature check failed. This deb might not be signed.\n");
 
-    char originID[2048];
-    strncpy(originID, tmpID, sizeof(originID));
+    strncpy(ds_ctx.originID, tmpID, sizeof(ds_ctx.originID));
 
     /* Now we have an ID, let's check the policy to use */
-    snprintf(buf, sizeof(buf) - 1, DEBSIG_POLICIES_DIR_FMT, rootdir, originID);
+    snprintf(buf, sizeof(buf) - 1, DEBSIG_POLICIES_DIR_FMT, rootdir, ds_ctx.originID);
     if ((pd = opendir(buf)) == NULL)
 	ds_fail_printf(DS_FAIL_UNKNOWN_ORIGIN,
 		       "Could not open Origin dir %s: %s\n", buf, strerror(errno));
@@ -412,7 +406,7 @@ int main(int argc, char *argv[]) {
 	/* Now let's see if this policy's selection is useful for this .deb  */
 	ds_printf(DS_LEV_VER, "    Checking Selection group(s).");
 	for (grp = pol->sels; grp != NULL; grp = grp->next) {
-            if (!checkSelRules(originID, grp, deb, deb_fs)) {
+            if (!checkSelRules(&ds_ctx, grp)) {
 		clear_policy();
 		ds_printf(DS_LEV_VER, "    Selection group failed checks.");
 		pol = NULL;
@@ -444,9 +438,9 @@ int main(int argc, char *argv[]) {
     ds_printf(DS_LEV_VER, "    Checking Verification group(s).");
 
     for (grp = pol->vers; grp; grp = grp->next) {
-        if (!verifyGroupRules(originID, grp, deb, deb_fs)) {
+        if (!verifyGroupRules(&ds_ctx, grp)) {
 	    ds_printf(DS_LEV_VER, "    Verification group failed checks.");
-	    ds_fail_printf(DS_FAIL_BADSIG, "Failed verification for %s.", deb);
+	    ds_fail_printf(DS_FAIL_BADSIG, "Failed verification for %s.", ds_ctx.deb);
 	}
     }
 
diff --git a/debsig.h b/debsig.h
index 367fb9a..ea6edb7 100644
--- a/debsig.h
+++ b/debsig.h
@@ -60,11 +60,20 @@ struct policy {
         struct group *vers;
 };
 
+// the debsig context
+struct debsig_ctx {
+   char *deb;
+   FILE *deb_fs;
+   char originID[2048];
+};
+
 struct policy *parsePolicyFile(const char *filename);
-off_t findMember(const char *deb, const char *name, FILE *deb_fs);
-off_t checkSigExist(const char *deb, const char *name, FILE *deb_fs);
+
+off_t findMember(const struct debsig_ctx *ds_ctx, const char *name);
+off_t checkSigExist(const struct debsig_ctx *ds_ctx, const char *name);
+char *getSigKeyID (const struct debsig_ctx *ds_ctx, const char *type);
+
 char *getKeyID (const char *originID, const struct match *mtc);
-char *getSigKeyID (const char *deb, const char *type);
 int gpgVerify(const char *originID, const char *data, struct match *mtc, const char *sig);
 void clear_policy(void);
 
diff --git a/gpg-parse.c b/gpg-parse.c
index 7c5b27c..146807c 100644
--- a/gpg-parse.c
+++ b/gpg-parse.c
@@ -97,19 +97,16 @@ char *getKeyID (const char *originID, const struct match *mtc) {
     return ret;
 }
 
-char *getSigKeyID (const char *deb, const char *type) {
+char *getSigKeyID (const struct debsig_ctx *ds_ctx, const char *type) {
     char buf[2048];
     int pread[2], pwrite[2], t;
     pid_t pid;
     FILE *ds_read, *ds_write;
     char *c, *ret = NULL;
 
-    FILE *deb_fs = fopen(deb, "r");
-    off_t len = checkSigExist(deb, type, deb_fs);
-    if (!len) {
-        fclose(deb_fs);
+    off_t len = checkSigExist(ds_ctx, type);
+    if (!len)
 	return NULL;
-    }
 
     gpg_init();
 
@@ -138,8 +135,8 @@ char *getSigKeyID (const char *deb, const char *type) {
     /* First, let's feed gpg our signature. Don't forget, our call to
      * checkSigExist() above positioned the deb_fs file pointer already.  */
     do {
-       t = fread(buf, 1, sizeof(buf), deb_fs);
-       if (ferror(deb_fs))
+       t = fread(buf, 1, sizeof(buf), ds_ctx->deb_fs);
+       if (ferror(ds_ctx->deb_fs))
           ds_fail_printf(DS_FAIL_INTERNAL, "getSigKeyID: error reading signature (%s)",
                          strerror(errno));
 
@@ -148,7 +145,7 @@ char *getSigKeyID (const char *deb, const char *type) {
 	else
 	    fwrite(buf, 1, t, ds_write);
 	len -= t;
-    } while(len > 0 || !feof(deb_fs));
+    } while(len > 0 || !feof(ds_ctx->deb_fs));
 
     if (ferror(ds_write))
 	ds_fail_printf(DS_FAIL_INTERNAL, "error writing to gpg");
@@ -179,7 +176,6 @@ char *getSigKeyID (const char *deb, const char *type) {
     else
 	ds_printf(DS_LEV_DEBUG, "        getSigKeyID: got %s for %s key", ret, type);
 
-    fclose(deb_fs);
     return ret;
 }
 
diff --git a/misc.c b/misc.c
index 03b6bd5..9219024 100644
--- a/misc.c
+++ b/misc.c
@@ -43,7 +43,7 @@ void ds_printf(int level, const char *fmt, ...) {
 }
 
 off_t
-checkSigExist(const char *deb, const char *name, FILE *deb_fs)
+checkSigExist(const struct debsig_ctx *ds_ctx, const char *name)
 {
     char buf[16];
 
@@ -54,5 +54,5 @@ checkSigExist(const char *deb, const char *name, FILE *deb_fs)
 
     snprintf(buf, sizeof(buf) - 1, "_gpg%s", name);
 
-    return findMember(deb, buf, deb_fs);
+    return findMember(ds_ctx, buf);
 }
-- 
2.0.0.rc0

Reply via email to