DKIM DNS TXT record bug fix. Fixes: #967
authorNigel Metheringham <nigel@exim.org>
Sat, 29 May 2010 19:23:25 +0000 (19:23 +0000)
committerNigel Metheringham <nigel@exim.org>
Sat, 29 May 2010 19:23:25 +0000 (19:23 +0000)
doc/doc-docbook/spec.xfpt
doc/doc-txt/ChangeLog
src/src/lookups/dnsdb.c

index 6a1d7ce..5385d8e 100644 (file)
@@ -1,4 +1,4 @@
-. $Cambridge: exim/doc/doc-docbook/spec.xfpt,v 1.72 2010/03/05 16:26:46 nm4 Exp $
+. $Cambridge: exim/doc/doc-docbook/spec.xfpt,v 1.73 2010/05/29 19:23:25 nm4 Exp $
 .
 . /////////////////////////////////////////////////////////////////////////////
 . This is the primary source of the Exim Manual. It is an xfpt document that is
@@ -6628,6 +6628,20 @@ ${lookup dnsdb{>: a=host1.example}}
 It is permitted to specify a space as the separator character. Further
 white space is ignored.
 
+.new
+.cindex "TXT record" "in &(dnsdb)& lookup"
+For TXT records with multiple items of data, only the first item is returned,
+unless a separator for them is specified using a comma after the separator
+character followed immediately by the TXT record item separator. To concatenate
+items without a separator, use a semicolon instead.
+.code
+${lookup dnsdb{>\n,: txt=a.b.example}}
+${lookup dnsdb{>\n; txt=a.b.example}}
+.endd
+It is permitted to specify a space as the separator character. Further
+white space is ignored.
+.wen
+
 .section "Pseudo dnsdb record types" "SECID66"
 .cindex "MX record" "in &(dnsdb)& lookup"
 By default, both the preference value and the host name are returned for
index a243412..372be8f 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.610 2010/05/29 19:16:50 nm4 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.611 2010/05/29 19:23:26 nm4 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -39,6 +39,9 @@ MH/01 Treat the transport option dkim_domain as a colon separated
 NM/07 Null terminate DKIM strings, Null initialise DKIM variable
       Bugzilla 985, 986.  Patch by Simon Arlott
 
+NM/08 Bugzilla 967. DKIM DNS TXT record bug fix
+      Patch by Simon Arlott
+
 
 Exim version 4.71
 -----------------
index 5e9741b..89ad67d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/lookups/dnsdb.c,v 1.19 2009/11/16 19:50:38 nm4 Exp $ */
+/* $Cambridge: exim/src/src/lookups/dnsdb.c,v 1.20 2010/05/29 19:23:26 nm4 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -88,17 +88,23 @@ consist of a number of parts.
 separator character that is used when multiple records are found. The default
 separator is newline.
 
-(b) If the next sequence of characters is 'defer_FOO' followed by a comma,
+(b) If the next character is ',' then the next character is the separator
+character used for multiple items of text in "TXT" records. Alternatively,
+if the next character is ';' then these multiple items are concatenated with
+no separator. With neither of these options specified, only the first item
+is output.
+
+(c) If the next sequence of characters is 'defer_FOO' followed by a comma,
 the defer behaviour is set to FOO. The possible behaviours are: 'strict', where
 any defer causes the whole lookup to defer; 'lax', where a defer causes the
 whole lookup to defer only if none of the DNS queries succeeds; and 'never',
 where all defers are as if the lookup failed. The default is 'lax'.
 
-(c) If the next sequence of characters is a sequence of letters and digits
+(d) If the next sequence of characters is a sequence of letters and digits
 followed by '=', it is interpreted as the name of the DNS record type. The
 default is "TXT".
 
-(d) Then there follows list of domain names. This is a generalized Exim list,
+(e) Then there follows list of domain names. This is a generalized Exim list,
 which may start with '<' in order to set a specific separator. The default
 separator, as always, is colon. */
 
@@ -114,6 +120,7 @@ int defer_mode = PASS;
 int type = T_TXT;
 int failrc = FAIL;
 uschar *outsep = US"\n";
+uschar *outsep2 = NULL;
 uschar *equals, *domain, *found;
 uschar buffer[256];
 
@@ -131,13 +138,24 @@ filename = filename;
 length = length;
 do_cache = do_cache;
 
-/* If the string starts with '>' we change the output separator */
+/* If the string starts with '>' we change the output separator.
+If it's followed by ';' or ',' we set the TXT output separator. */
 
 while (isspace(*keystring)) keystring++;
 if (*keystring == '>')
   {
   outsep = keystring + 1;
   keystring += 2;
+  if (*keystring == ',')
+    {
+    outsep2 = keystring + 1;
+    keystring += 2;
+    }
+  else if (*keystring == ';')
+    {
+    outsep2 = US"";
+    keystring++;
+    }
   while (isspace(*keystring)) keystring++;
   }
 
@@ -303,13 +321,25 @@ while ((domain = string_nextinlist(&keystring, &sep, buffer, sizeof(buffer)))
 
     if (type == T_TXT)
       {
-      int data_offset = 0;
-      while (data_offset < rr->size)
+      if (outsep2 == NULL)
         {
-        uschar chunk_len = (rr->data)[data_offset++];
-        yield = string_cat(yield, &size, &ptr,
-                           (uschar *)((rr->data)+data_offset), chunk_len);
-        data_offset += chunk_len;
+        /* output only the first item of data */
+        yield = string_cat(yield, &size, &ptr, (uschar *)(rr->data+1),
+          (rr->data)[0]);
+        }
+      else
+        {
+        /* output all items */
+        int data_offset = 0;
+        while (data_offset < rr->size)
+          {
+          uschar chunk_len = (rr->data)[data_offset++];
+          if (outsep2[0] != '\0' && data_offset != 1)
+            yield = string_cat(yield, &size, &ptr, outsep2, 1);
+          yield = string_cat(yield, &size, &ptr,
+                             (uschar *)((rr->data)+data_offset), chunk_len);
+          data_offset += chunk_len;
+          }
         }
       }
     else   /* T_CNAME, T_CSA, T_MX, T_MXH, T_NS, T_PTR, T_SRV */