Fix bug in relaxed body canon.
[exim.git] / src / src / pdkim / pdkim.c
index e269f7796455f8b000e5da25fc3d5ad3c0d11a36..dbc1f4d0cdd3df2b9cb7c89bbf22802480b18723 100644 (file)
@@ -20,7 +20,7 @@
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-/* $Cambridge: exim/src/src/pdkim/pdkim.c,v 1.2 2009/06/10 07:34:05 tom Exp $ */
+/* $Cambridge: exim/src/src/pdkim/pdkim.c,v 1.6 2009/10/29 11:08:01 tom Exp $ */
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -162,6 +162,17 @@ pdkim_stringlist *pdkim_append_stringlist(pdkim_stringlist *base, char *str) {
   }
   else return new_entry;
 };
+pdkim_stringlist *pdkim_prepend_stringlist(pdkim_stringlist *base, char *str) {
+  pdkim_stringlist *new_entry = malloc(sizeof(pdkim_stringlist));
+  if (new_entry == NULL) return NULL;
+  memset(new_entry,0,sizeof(pdkim_stringlist));
+  new_entry->value = strdup(str);
+  if (new_entry->value == NULL) return NULL;
+  if (base != NULL) {
+    new_entry->next = base;
+  }
+  return new_entry;
+};
 
 
 /* -------------------------------------------------------------------------- */
@@ -355,7 +366,7 @@ char *pdkim_relax_header (char *header, int crlf) {
   int seen_wsp = 0;
   char *p = header;
   char *q;
-  char *relaxed = malloc(strlen(header));
+  char *relaxed = malloc(strlen(header)+3);
   if (relaxed == NULL) return NULL;
   q = relaxed;
   while (*p != '\0') {
@@ -853,7 +864,10 @@ int pdkim_update_bodyhash(pdkim_ctx *ctx, char *data, int len) {
         if (relaxed_data == NULL) return PDKIM_ERR_OOM;
         while (*p != '\0') {
           char c = *p;
-          if ( (c == '\t') || (c == ' ') ) {
+          if (c == '\r') {
+            if ( (q > 0) && (relaxed_data[q-1] == ' ') ) q--;
+          }
+          else if ( (c == '\t') || (c == ' ') ) {
             c = ' '; /* Turns WSP into SP */
             if (seen_wsp) {
               p++;
@@ -1045,9 +1059,9 @@ int pdkim_header_complete(pdkim_ctx *ctx) {
                             sig->hnames_check, 1) != PDKIM_OK) goto NEXT_SIG;
     }
 
-    /* Add header to the signed headers list */
-    list = pdkim_append_stringlist(sig->headers,
-                                   ctx->cur_header->str);
+    /* Add header to the signed headers list (in reverse order) */
+    list = pdkim_prepend_stringlist(sig->headers,
+                                    ctx->cur_header->str);
     if (list == NULL) return PDKIM_ERR_OOM;
     sig->headers = list;
 
@@ -1347,7 +1361,8 @@ DLLEXPORT int pdkim_feed_finish(pdkim_ctx *ctx, pdkim_signature **return_signatu
         q = strchr(p,':');
         if (q != NULL) *q = '\0';
         while (hdrs != NULL) {
-          if (strncasecmp(hdrs->value,p,strlen(p)) == 0) {
+          if ( (strncasecmp(hdrs->value,p,strlen(p)) == 0) &&
+               ((hdrs->value)[strlen(p)] == ':') ) {
             char *rh = NULL;
             if (sig->canon_headers == PDKIM_CANON_RELAXED)
               rh = pdkim_relax_header(hdrs->value,1); /* cook header for relaxed canon */
@@ -1364,6 +1379,8 @@ DLLEXPORT int pdkim_feed_finish(pdkim_ctx *ctx, pdkim_signature **return_signatu
               pdkim_quoteprint(ctx->debug_stream, rh, strlen(rh), 1);
             #endif
             free(rh);
+            (hdrs->value)[0] = '_';
+            break;
           }
           hdrs = hdrs->next;
         }