Re: [exim-dev] [exim] Using ADSP?

Top Page
Delete this message
Reply to this message
Author: Michael Haardt
Date:  
To: exim-dev
Subject: Re: [exim-dev] [exim] Using ADSP?
Let's move this to exim-dev.

> > It does not look like I can add multiple signatures, though, because
> > dkim_domain is not a list that sets $dkim_domain to each element,
> > expanding dkim_selector and dkim_private_key using that value and acting
> > upon it. Any other way?
>
> Sorry, signing with several sigs concurrently is not supported (at least
> not without looping the message through several processes). I know
> you're quite the versatile guy, so if you want to take a shot at an
> implementation ... go ahead :)


The patch below sketches my suggestion in terms of code (neither tested
not finished). I broke indentation for a readable patch, the whole
block inside the loop should be indented of course. The transport option
dkim_domain should be renamed to dkim_add_signers, because that's what
it does. It may be a good idea not to add signatures already existing
in the mail, e.g. by initialising the seen_items code. Should that be
configurable?

What I meant to implement is a loop through all signers, much like
verification works. For each signer, available in $dkim_domain, the
other dkim transport options are expanded and if there is a $dkim_key
afterwards, the mail is signed using those values.

Any opinions are welcome.

Michael
----------------------------------------------------------------------
--- ./src/dkim.c.orig    2010-01-27 11:05:45.000000000 +0100
+++ ./src/dkim.c    2010-01-27 14:20:34.000000000 +0100
@@ -387,6 +387,14 @@
                        uschar *dkim_selector,
                        uschar *dkim_canon,
                        uschar *dkim_sign_headers) {
+  int sep = 0;
+  uschar *seen_items = NULL;
+  int seen_items_size = 0;
+  int seen_items_offset = 0;
+  uschar itembuf[256];
+  uschar *dkim_canon_expanded;
+  uschar *dkim_sign_headers_expanded;
+  uschar *dkim_private_key_expanded;
   pdkim_ctx *ctx = NULL;
   uschar *rc = NULL;
   pdkim_signature *signature;
@@ -405,42 +413,54 @@
     rc = NULL;
     goto CLEANUP;
   }
-  /* Set up $dkim_domain expansion variable. */
-  dkim_signing_domain = dkim_domain;


-  /* Get selector to use. */
-  dkim_selector = expand_string(dkim_selector);
-  if (dkim_selector == NULL) {
+  /* Set $dkim_domain expansion variable to each unique domain in list. */
+  while ((dkim_signing_domain = string_nextinlist(&dkim_domain, &sep,
+                                                  itembuf,
+                                                  sizeof(itembuf))) != NULL) {
+    if (!dkim_signing_domain || (dkim_signing_domain[0] == '\0')) continue;
+    /* Only sign once for each domain, no matter how often it
+       appears in the expanded list. */
+    if (seen_items != NULL) {
+      uschar *seen_items_list = seen_items;
+      if (match_isinlist(dkim_signing_domain,
+                         &seen_items_list,0,NULL,NULL,MCL_STRING,TRUE,NULL) == OK)
+        continue;
+      seen_items = string_append(seen_items,&seen_items_size,&seen_items_offset,1,":");
+    }
+    seen_items = string_append(seen_items,&seen_items_size,&seen_items_offset,1,dkim_signing_domain);
+    seen_items[seen_items_offset] = '\0';
+
+  /* Set up $dkim_selector expansion variable. */
+  dkim_signing_selector = expand_string(dkim_selector);
+  if (dkim_signing_selector == NULL) {
     log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
       "dkim_selector: %s", expand_string_message);
     rc = NULL;
     goto CLEANUP;
   }
-  /* Set up $dkim_selector expansion variable. */
-  dkim_signing_selector = dkim_selector;


   /* Get canonicalization to use */
-  dkim_canon = expand_string(dkim_canon?dkim_canon:US"relaxed");
-  if (dkim_canon == NULL) {
+  dkim_canon_expanded = expand_string(dkim_canon?dkim_canon:US"relaxed");
+  if (dkim_canon_expanded == NULL) {
     /* expansion error, do not send message. */
     log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
           "dkim_canon: %s", expand_string_message);
     rc = NULL;
     goto CLEANUP;
   }
-  if (Ustrcmp(dkim_canon, "relaxed") == 0)
+  if (Ustrcmp(dkim_canon_expanded, "relaxed") == 0)
     pdkim_canon = PDKIM_CANON_RELAXED;
-  else if (Ustrcmp(dkim_canon, "simple") == 0)
+  else if (Ustrcmp(dkim_canon_expanded, "simple") == 0)
     pdkim_canon = PDKIM_CANON_SIMPLE;
   else {
-    log_write(0, LOG_MAIN, "DKIM: unknown canonicalization method '%s', defaulting to 'relaxed'.\n",dkim_canon);
+    log_write(0, LOG_MAIN, "DKIM: unknown canonicalization method '%s', defaulting to 'relaxed'.\n",dkim_canon_expanded);
     pdkim_canon = PDKIM_CANON_RELAXED;
   }


-  /* Expand signing headers once */
   if (dkim_sign_headers != NULL) {
-    dkim_sign_headers = expand_string(dkim_sign_headers);
-    if (dkim_sign_headers == NULL) {
+    dkim_sign_headers_expanded = expand_string(dkim_sign_headers);
+    if (dkim_sign_headers_expanded == NULL) {
       log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
         "dkim_sign_headers: %s", expand_string_message);
       rc = NULL;
@@ -449,47 +469,49 @@
   }


   /* Get private key to use. */
-  dkim_private_key = expand_string(dkim_private_key);
-  if (dkim_private_key == NULL) {
+  dkim_private_key_expanded = expand_string(dkim_private_key);
+  if (dkim_private_key_expanded == NULL) {
     log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
       "dkim_private_key: %s", expand_string_message);
     rc = NULL;
     goto CLEANUP;
   }
-  if ( (Ustrlen(dkim_private_key) == 0) ||
-       (Ustrcmp(dkim_private_key,"0") == 0) ||
-       (Ustrcmp(dkim_private_key,"false") == 0) ) {
+  if ( (Ustrlen(dkim_private_key_expanded) == 0) ||
+       (Ustrcmp(dkim_private_key_expanded,"0") == 0) ||
+       (Ustrcmp(dkim_private_key_expanded,"false") == 0) ) {
     /* don't sign, but no error */
     rc = US"";
     goto CLEANUP;
   }


-  if (dkim_private_key[0] == '/') {
+
+
+  if (dkim_private_key_expanded[0] == '/') {
     int privkey_fd = 0;
     /* Looks like a filename, load the private key. */
     memset(big_buffer,0,big_buffer_size);
-    privkey_fd = open(CS dkim_private_key,O_RDONLY);
+    privkey_fd = open(CS dkim_private_key_expanded,O_RDONLY);
     if (privkey_fd < 0) {
       log_write(0, LOG_MAIN|LOG_PANIC, "unable to open "
-        "private key file for reading: %s", dkim_private_key);
+        "private key file for reading: %s", dkim_private_key_expanded);
       rc = NULL;
       goto CLEANUP;
     }
     (void)read(privkey_fd,big_buffer,(big_buffer_size-2));
     (void)close(privkey_fd);
-    dkim_private_key = big_buffer;
+    dkim_private_key_expanded = big_buffer;
   }


   ctx = pdkim_init_sign(PDKIM_INPUT_SMTP,
                         (char *)dkim_signing_domain,
                         (char *)dkim_signing_selector,
-                        (char *)dkim_private_key
+                        (char *)dkim_private_key_expanded
                        );


pdkim_set_debug_stream(ctx,debug_file);

   pdkim_set_optional(ctx,
-                     (char *)dkim_sign_headers,
+                     (char *)dkim_sign_headers_expanded,
                      NULL,
                      pdkim_canon,
                      pdkim_canon,
@@ -522,6 +544,11 @@
   Ustrcpy(rc,US signature->signature_header);
   Ustrcat(rc,US"\r\n");


+  pdkim_free_ctx(ctx);
+  ctx = NULL;
+
+  }
+
   CLEANUP:
   if (ctx != NULL) {
     pdkim_free_ctx(ctx);