From 31f73fa0b290503d4e125d421a7ba13246121a42 Mon Sep 17 00:00:00 2001 From: Tom Kistner Date: Thu, 30 Apr 2009 15:25:39 +0000 Subject: [PATCH] Change verification logic: headers do not need to be in the sequence specified in h= --- src/src/pdkim/pdkim.c | 50 +++++++++++++++++++++++++------------------ src/src/pdkim/pdkim.h | 8 ++++--- 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/src/pdkim/pdkim.c b/src/src/pdkim/pdkim.c index da82fb7c8..a4be815ad 100644 --- a/src/src/pdkim/pdkim.c +++ b/src/src/pdkim/pdkim.c @@ -20,7 +20,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -/* $Cambridge: exim/src/src/pdkim/pdkim.c,v 1.1.2.12 2009/04/09 19:18:11 tom Exp $ */ +/* $Cambridge: exim/src/src/pdkim/pdkim.c,v 1.1.2.13 2009/04/30 15:25:39 tom Exp $ */ #include #include @@ -270,6 +270,7 @@ void pdkim_free_sig(pdkim_signature *sig) { if (sig->signature_header != NULL) free(sig->signature_header); if (sig->sha1_body != NULL) free(sig->sha1_body); if (sig->sha2_body != NULL) free(sig->sha2_body); + if (sig->hnames_check != NULL) free(sig->hnames_check); if (sig->pubkey != NULL) pdkim_free_pubkey(sig->pubkey); @@ -295,21 +296,24 @@ DLLEXPORT void pdkim_free_ctx(pdkim_ctx *ctx) { "start". Returns the position of the header name in the list. */ int header_name_match(char *header, - char *list, - int start) { + char *tick, + int do_tick) { char *hname; char *lcopy; char *p; char *q; - int pos = 0; int rc = PDKIM_FAIL; + + /* Get header name */ char *hcolon = strchr(header,':'); if (hcolon == NULL) return rc; /* This isn't a header */ hname = malloc((hcolon-header)+1); if (hname == NULL) return PDKIM_ERR_OOM; memset(hname,0,(hcolon-header)+1); strncpy(hname,header,(hcolon-header)); - lcopy = strdup(list); + + /* Copy tick-off list locally, so we can punch zeroes into it */ + lcopy = strdup(tick); if (lcopy == NULL) { free(hname); return PDKIM_ERR_OOM; @@ -318,20 +322,24 @@ int header_name_match(char *header, q = strchr(p,':'); while (q != NULL) { *q = '\0'; - if (pos >= start) { - if (strcasecmp(p,hname) == 0) { - rc = pos; - goto BAIL; - } + + if (strcasecmp(p,hname) == 0) { + rc = PDKIM_OK; + /* Invalidate header name instance in tick-off list */ + if (do_tick) tick[p-lcopy] = '_'; + goto BAIL; } + p = q+1; q = strchr(p,':'); - pos++; } - if (pos >= start) { - if (strcasecmp(p,hname) == 0) - rc = pos; + + if (strcasecmp(p,hname) == 0) { + rc = PDKIM_OK; + /* Invalidate header name instance in tick-off list */ + if (do_tick) tick[p-lcopy] = '_'; } + BAIL: free(hname); free(lcopy); @@ -660,6 +668,9 @@ pdkim_signature *pdkim_parse_sig_header(pdkim_ctx *ctx, char *raw_hdr) { return NULL; } + /* Copy header list to 'tick-off' header list */ + sig->hnames_check = strdup(sig->headernames); + *q = '\0'; /* Chomp raw header. The final newline must not be added to the signature. */ q--; @@ -1024,16 +1035,13 @@ int pdkim_header_complete(pdkim_ctx *ctx) { if (header_name_match(ctx->cur_header->str, sig->sign_headers? sig->sign_headers: - PDKIM_DEFAULT_SIGN_HEADERS, 0) < 0) goto NEXT_SIG; + PDKIM_DEFAULT_SIGN_HEADERS, 0) != PDKIM_OK) goto NEXT_SIG; } /* VERIFICATION --------------------------------------------------------- */ else { - int rc = header_name_match(ctx->cur_header->str, - sig->headernames, - sig->headernames_pos); - /* Header is not included or out-of-sequence */ - if (rc < 0) goto NEXT_SIG; - sig->headernames_pos = rc; + /* Header is not included or all instances were already 'ticked off' */ + if (header_name_match(ctx->cur_header->str, + sig->hnames_check, 1) != PDKIM_OK) goto NEXT_SIG; } /* Add header to the signed headers list */ diff --git a/src/src/pdkim/pdkim.h b/src/src/pdkim/pdkim.h index 1872f1497..0e884dde2 100644 --- a/src/src/pdkim/pdkim.h +++ b/src/src/pdkim/pdkim.h @@ -20,7 +20,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -/* $Cambridge: exim/src/src/pdkim/pdkim.h,v 1.1.2.10 2009/04/09 13:57:21 tom Exp $ */ +/* $Cambridge: exim/src/src/pdkim/pdkim.h,v 1.1.2.11 2009/04/30 15:25:39 tom Exp $ */ /* -------------------------------------------------------------------------- */ /* Debugging. This can also be enabled/disabled at run-time. I recommend to @@ -240,7 +240,9 @@ typedef struct pdkim_signature { char *rsa_privkey; /* Private RSA key */ char *sign_headers; /* To-be-signed header names */ /* Verification specific -------------------------------------------- */ - int headernames_pos; /* Current position in header name list */ + char *hnames_check; /* Tick-off header list that we use to keep + track of header names that we have already + added to the signature */ char *rawsig_no_b_val; /* Original signature header w/o b= tag value. */ } pdkim_signature; @@ -306,7 +308,7 @@ int pdkim_set_optional (pdkim_ctx *, char *, char *,int, int, unsigned long); DLLEXPORT -int pdkim_feed (pdkim_ctx *, char *, int); +int pdkim_feed (pdkim_ctx *, char *, int); DLLEXPORT int pdkim_feed_finish (pdkim_ctx *, pdkim_signature **); -- 2.30.2