From 0d0c6357ebfc93f3119d2118dbeb62a8ad50c678 Mon Sep 17 00:00:00 2001 From: Nigel Metheringham Date: Sat, 29 May 2010 19:23:25 +0000 Subject: [PATCH] DKIM DNS TXT record bug fix. Fixes: #967 --- doc/doc-docbook/spec.xfpt | 16 +++++++++++- doc/doc-txt/ChangeLog | 5 +++- src/src/lookups/dnsdb.c | 52 ++++++++++++++++++++++++++++++--------- 3 files changed, 60 insertions(+), 13 deletions(-) diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index 6a1d7ce12..5385d8ead 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -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 diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index a2434129c..372be8fdf 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -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 ----------------- diff --git a/src/src/lookups/dnsdb.c b/src/src/lookups/dnsdb.c index 5e9741bea..89ad67d28 100644 --- a/src/src/lookups/dnsdb.c +++ b/src/src/lookups/dnsdb.c @@ -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 */ -- 2.30.2