summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTodd Lyons <tlyons@exim.org>2014-04-15 09:53:43 -0700
committerTodd Lyons <tlyons@exim.org>2014-04-15 09:53:43 -0700
commit364e49ab87bf81774f12f8b0e21509eb51c88b71 (patch)
tree86b43906007d8a6cee2f7ad7cea22f2f8aff8a55 /src
parent3695be34bdae5e69ed8188587f03b87b6e929d42 (diff)
parent10cc8a1e4c3077eefcb37878990753d1d49cf363 (diff)
Merge branch 'master' of ssh://git.exim.org/home/git/exim
Fixed Conflicts: doc/doc-txt/ChangeLog
Diffstat (limited to 'src')
-rw-r--r--src/OS/Makefile-Base20
-rw-r--r--src/src/dns.c1
-rw-r--r--src/src/exim.h6
-rw-r--r--src/src/expand.c9
-rw-r--r--src/src/functions.h1
-rw-r--r--src/src/lookups/dnsdb.c30
-rw-r--r--src/src/readconf.c24
-rw-r--r--src/src/routers/rf_get_munge_headers.c99
-rw-r--r--src/src/string.c44
-rw-r--r--src/src/transport.c76
10 files changed, 199 insertions, 111 deletions
diff --git a/src/OS/Makefile-Base b/src/OS/Makefile-Base
index f0edbf132..8209969f6 100644
--- a/src/OS/Makefile-Base
+++ b/src/OS/Makefile-Base
@@ -316,8 +316,8 @@ OBJ_EXIM = acl.o child.o crypt16.o daemon.o dbfn.o debug.o deliver.o \
local_scan.o $(EXIM_PERL) $(OBJ_WITH_CONTENT_SCAN) \
$(OBJ_WITH_OLD_DEMIME) $(OBJ_EXPERIMENTAL)
-exim: lookups/lookups.a auths/auths.a pdkim/pdkim.a \
- routers/routers.a transports/transports.a \
+exim: buildlookups buildauths pdkim/pdkim.a \
+ buildrouters buildtransports \
$(OBJ_EXIM) version.o
@echo "$(LNCC) -o exim"
$(FE)$(PURIFY) $(LNCC) -o exim $(LFLAGS) $(OBJ_EXIM) version.o \
@@ -354,7 +354,7 @@ exim_dumpdb: $(OBJ_DUMPDB)
OBJ_FIXDB = exim_fixdb.o util-os.o util-store.o
-exim_fixdb: $(OBJ_FIXDB) auths/auths.a
+exim_fixdb: $(OBJ_FIXDB) buildauths
@echo "$(LNCC) -o exim_fixdb"
$(FE)$(LNCC) $(CFLAGS) $(INCLUDE) -o exim_fixdb $(LFLAGS) $(OBJ_FIXDB) \
auths/auths.a $(LIBS) $(EXTRALIBS) $(DBMLIB)
@@ -620,7 +620,7 @@ drtables.o: $(HDRS) drtables.c
# When using parallel make, we don't have the dependency to force building
# in the sub-directory unless we force that dependency:
-$(OBJ_LOOKUPS): lookups/lookups.a
+$(OBJ_LOOKUPS): buildlookups
# The exim monitor's private modules - the sources live in a private
# subdirectory. The final binary combines the private modules with some
@@ -648,8 +648,7 @@ $(MONBIN): $(HDRS)
# The lookups library.
-buildlookups: lookups/lookups.a
-lookups/lookups.a: config.h version.h
+buildlookups:
@cd lookups && $(MAKE) SHELL=$(SHELL) AR="$(AR)" $(MFLAGS) CC="$(CC)" CFLAGS="$(CFLAGS)" \
CFLAGS_DYNAMIC="$(CFLAGS_DYNAMIC)" HDRS="../version.h $(PHDRS)" \
FE="$(FE)" RANLIB="$(RANLIB)" RM_COMMAND="$(RM_COMMAND)" \
@@ -658,8 +657,7 @@ lookups/lookups.a: config.h version.h
# The routers library.
-buildrouters: routers/routers.a
-routers/routers.a: config.h
+buildrouters:
@cd routers && $(MAKE) SHELL=$(SHELL) AR="$(AR)" $(MFLAGS) CC="$(CC)" CFLAGS="$(CFLAGS)" \
FE="$(FE)" RANLIB="$(RANLIB)" RM_COMMAND="$(RM_COMMAND)" HDRS="$(PHDRS)" \
INCLUDE="$(INCLUDE) $(IPV6_INCLUDE) $(TLS_INCLUDE)"
@@ -667,8 +665,7 @@ routers/routers.a: config.h
# The transports library.
-buildtransports: transports/transports.a
-transports/transports.a: config.h
+buildtransports:
@cd transports && $(MAKE) SHELL=$(SHELL) AR="$(AR)" $(MFLAGS) CC="$(CC)" CFLAGS="$(CFLAGS)" \
FE="$(FE)" RANLIB="$(RANLIB)" RM_COMMAND="$(RM_COMMAND)" HDRS="$(PHDRS)" \
INCLUDE="$(INCLUDE) $(IPV6_INCLUDE) $(TLS_INCLUDE)"
@@ -676,8 +673,7 @@ transports/transports.a: config.h
# The library of authorization modules
-buildauths: auths/auths.a
-auths/auths.a: config.h
+buildauths:
@cd auths && $(MAKE) SHELL=$(SHELL) AR="$(AR)" $(MFLAGS) CC="$(CC)" CFLAGS="$(CFLAGS)" \
FE="$(FE)" RANLIB="$(RANLIB)" RM_COMMAND="$(RM_COMMAND)" HDRS="$(PHDRS)" \
INCLUDE="$(INCLUDE) $(IPV6_INCLUDE) $(TLS_INCLUDE)"
diff --git a/src/src/dns.c b/src/src/dns.c
index 88fa36baa..2aeb5af62 100644
--- a/src/src/dns.c
+++ b/src/src/dns.c
@@ -479,6 +479,7 @@ switch(t)
case T_SRV: return US"SRV";
case T_NS: return US"NS";
case T_CNAME: return US"CNAME";
+ case T_TLSA: return US"TLSA";
default: return US"?";
}
}
diff --git a/src/src/exim.h b/src/src/exim.h
index b2d47d74e..c72c1f10a 100644
--- a/src/src/exim.h
+++ b/src/src/exim.h
@@ -321,6 +321,12 @@ header files. I don't suppose they have T_SRV either. */
#define T_SPF 99
#endif
+/* New TLSA record for DANE */
+#ifndef T_TLSA
+#define T_TLSA 52
+#endif
+#define MAX_TLSA_EXPANDED_SIZE 8192
+
/* It seems that some versions of arpa/nameser.h don't define *any* of the
T_xxx macros, which seem to be non-standard nowadays. Just to be on the safe
side, put in definitions for all the ones that Exim uses. */
diff --git a/src/src/expand.c b/src/src/expand.c
index 64a3a86e6..7a3252eaa 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -6189,8 +6189,13 @@ while (*s != 0)
}
if((c & 0xe0) == 0xc0) /* 2-byte sequence */
{
- bytes_left = 1;
- codepoint = c & 0x1f;
+ if(c == 0xc0 || c == 0xc1) /* 0xc0 and 0xc1 are illegal */
+ complete = -1;
+ else
+ {
+ bytes_left = 1;
+ codepoint = c & 0x1f;
+ }
}
else if((c & 0xf0) == 0xe0) /* 3-byte sequence */
{
diff --git a/src/src/functions.h b/src/src/functions.h
index 395961530..35500a165 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -350,6 +350,7 @@ extern int stdin_feof(void);
extern int stdin_ferror(void);
extern int stdin_ungetc(int);
extern uschar *string_append(uschar *, int *, int *, int, ...);
+extern uschar *string_append_listele(uschar *, uschar, const uschar *);
extern uschar *string_base62(unsigned long int);
extern uschar *string_cat(uschar *, int *, int *, const uschar *, int);
extern uschar *string_copy_dnsdomain(uschar *);
diff --git a/src/src/lookups/dnsdb.c b/src/src/lookups/dnsdb.c
index a8eab2e47..beba09508 100644
--- a/src/src/lookups/dnsdb.c
+++ b/src/src/lookups/dnsdb.c
@@ -22,6 +22,11 @@ header files. */
#define T_SPF 99
#endif
+/* New TLSA record for DANE */
+#ifndef T_TLSA
+#define T_TLSA 52
+#endif
+
/* Table of recognized DNS record types and their integer values. */
static const char *type_names[] = {
@@ -41,6 +46,7 @@ static const char *type_names[] = {
"ptr",
"spf",
"srv",
+ "tlsa",
"txt",
"zns"
};
@@ -62,6 +68,7 @@ static int type_values[] = {
T_PTR,
T_SPF,
T_SRV,
+ T_TLSA,
T_TXT,
T_ZNS /* Private type for "zone nameservers" */
};
@@ -378,6 +385,29 @@ while ((domain = string_nextinlist(&keystring, &sep, buffer, sizeof(buffer)))
}
}
}
+ else if (type == T_TLSA)
+ {
+ uint8_t usage, selector, matching_type;
+ uint16_t i, payload_length;
+ uschar s[MAX_TLSA_EXPANDED_SIZE];
+ uschar * sp = s;
+ uschar *p = (uschar *)(rr->data);
+
+ usage = *p++;
+ selector = *p++;
+ matching_type = *p++;
+ /* What's left after removing the first 3 bytes above */
+ payload_length = rr->size - 3;
+ sp += sprintf(CS s, "%d %d %d ", usage, selector, matching_type);
+ /* Now append the cert/identifier, one hex char at a time */
+ for (i=0;
+ i < payload_length && sp-s < (MAX_TLSA_EXPANDED_SIZE - 4);
+ i++)
+ {
+ sp += sprintf(CS sp, "%02x", (unsigned char)p[i]);
+ }
+ yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
+ }
else /* T_CNAME, T_CSA, T_MX, T_MXH, T_NS, T_PTR, T_SRV */
{
int priority, weight, port;
diff --git a/src/src/readconf.c b/src/src/readconf.c
index b41d22d2a..81e3bc267 100644
--- a/src/src/readconf.c
+++ b/src/src/readconf.c
@@ -1562,15 +1562,21 @@ switch (type)
Because we only do this once, near process start-up, I'm prepared to
let this slide for the time being, even though it rankles. */
}
- else if (*str_target && (ol->type & opt_rep_str))
- {
+ else if (ol->type & opt_rep_str)
+ {
uschar sep = Ustrncmp(name, "headers_add", 11)==0 ? '\n' : ':';
- saved_condition = *str_target;
- strtemp = saved_condition + Ustrlen(saved_condition)-1;
- if (*strtemp == sep) *strtemp = 0; /* eliminate trailing list-sep */
- strtemp = string_sprintf("%s%c%s", saved_condition, sep, sptr);
- *str_target = string_copy_malloc(strtemp);
- }
+ uschar * cp;
+
+ /* Strip trailing whitespace and seperators */
+ for (cp = sptr + Ustrlen(sptr) - 1;
+ cp >= sptr && (*cp == '\n' || *cp == '\t' || *cp == ' ' || *cp == sep);
+ cp--) *cp = '\0';
+
+ if (cp >= sptr)
+ *str_target = string_copy_malloc(
+ *str_target ? string_sprintf("%s%c%s", *str_target, sep, sptr)
+ : sptr);
+ }
else
{
*str_target = sptr;
@@ -4131,4 +4137,6 @@ while(next_section[0] != 0)
(void)fclose(config_file);
}
+/* vi: aw ai sw=2
+*/
/* End of readconf.c */
diff --git a/src/src/routers/rf_get_munge_headers.c b/src/src/routers/rf_get_munge_headers.c
index 76e87e9c7..c44ba70b8 100644
--- a/src/src/routers/rf_get_munge_headers.c
+++ b/src/src/routers/rf_get_munge_headers.c
@@ -13,7 +13,7 @@
* Get additional headers for a router *
*************************************************/
-/* This function is called by both routers to sort out the additional headers
+/* This function is called by routers to sort out the additional headers
and header remove list for a particular address.
Arguments:
@@ -32,83 +32,78 @@ rf_get_munge_headers(address_item *addr, router_instance *rblock,
header_line **extra_headers, uschar **remove_headers)
{
/* Default is to retain existing headers */
-
*extra_headers = addr->p.extra_headers;
-if (rblock->extra_headers != NULL)
+if (rblock->extra_headers)
{
- header_line *h;
- uschar *s = expand_string(rblock->extra_headers);
+ uschar * list = rblock->extra_headers;
+ int sep = '\n';
+ uschar * s;
+ int slen;
- if (s == NULL)
- {
- if (!expand_string_forcedfail)
+ while ((s = string_nextinlist(&list, &sep, NULL, 0)))
+ if (!(s = expand_string(s)))
{
- addr->message = string_sprintf("%s router failed to expand \"%s\": %s",
- rblock->name, rblock->extra_headers, expand_string_message);
- return DEFER;
+ if (!expand_string_forcedfail)
+ {
+ addr->message = string_sprintf("%s router failed to expand \"%s\": %s",
+ rblock->name, rblock->extra_headers, expand_string_message);
+ return DEFER;
+ }
}
- }
-
- /* Expand succeeded. Put extra header at the start of the chain because
- further down it may point to headers from other routers, which may be
- shared with other addresses. The output function outputs them in reverse
- order. */
-
- else
- {
- int slen = Ustrlen(s);
- if (slen > 0)
+ else if ((slen = Ustrlen(s)) > 0)
{
- h = store_get(sizeof(header_line));
+ /* Expand succeeded. Put extra headers at the start of the chain because
+ further down it may point to headers from other routers, which may be
+ shared with other addresses. The output function outputs them in reverse
+ order. */
+
+ header_line * h = store_get(sizeof(header_line));
/* We used to use string_sprintf() to add the newline if needed, but that
causes problems if the header line is exceedingly long (e.g. adding
something to a pathologically long line). So avoid it. */
if (s[slen-1] == '\n')
- {
- h->text = s;
- }
+ h->text = s;
else
- {
- h->text = store_get(slen+2);
- memcpy(h->text, s, slen);
- h->text[slen++] = '\n';
- h->text[slen] = 0;
- }
-
- h->next = addr->p.extra_headers;
+ {
+ h->text = store_get(slen+2);
+ memcpy(h->text, s, slen);
+ h->text[slen++] = '\n';
+ h->text[slen] = 0;
+ }
+
+ h->next = *extra_headers;
h->type = htype_other;
h->slen = slen;
*extra_headers = h;
}
- }
}
/* Default is to retain existing removes */
-
*remove_headers = addr->p.remove_headers;
-if (rblock->remove_headers != NULL)
+/* Expand items from colon-sep list separately, then build new list */
+if (rblock->remove_headers)
{
- uschar *s = expand_string(rblock->remove_headers);
- if (s == NULL)
- {
- if (!expand_string_forcedfail)
+ uschar * list = rblock->remove_headers;
+ int sep = ':';
+ uschar * s;
+ uschar buffer[128];
+
+ while ((s = string_nextinlist(&list, &sep, buffer, sizeof(buffer))))
+ if (!(s = expand_string(s)))
{
- addr->message = string_sprintf("%s router failed to expand \"%s\": %s",
- rblock->name, rblock->remove_headers, expand_string_message);
- return DEFER;
+ if (!expand_string_forcedfail)
+ {
+ addr->message = string_sprintf("%s router failed to expand \"%s\": %s",
+ rblock->name, rblock->remove_headers, expand_string_message);
+ return DEFER;
+ }
}
- }
- else if (*s != 0)
- {
- if (addr->p.remove_headers == NULL)
- *remove_headers = s;
- else
- *remove_headers = string_sprintf("%s : %s", addr->p.remove_headers, s);
- }
+ else if (*s)
+ *remove_headers = string_append_listele(*remove_headers, ':', s);
}
return OK;
diff --git a/src/src/string.c b/src/src/string.c
index 6f54cc624..eb73fae3e 100644
--- a/src/src/string.c
+++ b/src/src/string.c
@@ -966,6 +966,50 @@ return buffer;
#endif /* COMPILE_UTILITY */
+#ifndef COMPILE_UTILITY
+/************************************************
+* Add element to seperated list *
+************************************************/
+/* This function is used to build a list, returning
+an allocated null-terminated growable string. The
+given element has any embedded seperator characters
+doubled.
+
+Arguments:
+ list points to the start of the list that is being built, or NULL
+ if this is a new list that has no contents yet
+ sep list seperator charactoer
+ ele new lement to be appended to the list
+
+Returns: pointer to the start of the list, changed if copied for expansion.
+*/
+
+uschar *
+string_append_listele(uschar * list, uschar sep, const uschar * ele)
+{
+uschar * new = NULL;
+int sz = 0, off = 0;
+uschar * sp;
+
+if (list)
+ {
+ new = string_cat(new, &sz, &off, list, Ustrlen(list));
+ new = string_cat(new, &sz, &off, &sep, 1);
+ }
+
+while (sp = Ustrchr(ele, sep))
+ {
+ new = string_cat(new, &sz, &off, ele, sp-ele+1);
+ new = string_cat(new, &sz, &off, &sep, 1);
+ ele = sp+1;
+ }
+new = string_cat(new, &sz, &off, ele, Ustrlen(ele));
+new[off] = '\0';
+return new;
+}
+#endif /* COMPILE_UTILITY */
+
+
#ifndef COMPILE_UTILITY
/*************************************************
diff --git a/src/src/transport.c b/src/src/transport.c
index 549da4694..d4495393b 100644
--- a/src/src/transport.c
+++ b/src/src/transport.c
@@ -626,19 +626,9 @@ header_line *h;
/* Then the message's headers. Don't write any that are flagged as "old";
that means they were rewritten, or are a record of envelope rewriting, or
were removed (e.g. Bcc). If remove_headers is not null, skip any headers that
-match any entries therein. Then check addr->p.remove_headers too, provided that
-addr is not NULL. */
-
-if (remove_headers)
- {
- uschar *s = expand_string(remove_headers);
- if (!s && !expand_string_forcedfail)
- {
- errno = ERRNO_CHHEADER_FAIL;
- return FALSE;
- }
- remove_headers = s;
- }
+match any entries therein. It is a colon-sep list; expand the items
+separately and squash any empty ones.
+Then check addr->p.remove_headers too, provided that addr is not NULL. */
for (h = header_list; h != NULL; h = h->next) if (h->type != htype_old)
{
@@ -656,7 +646,15 @@ for (h = header_list; h != NULL; h = h->next) if (h->type != htype_old)
uschar buffer[128];
while ((s = string_nextinlist(&list, &sep, buffer, sizeof(buffer))))
{
- int len = Ustrlen(s);
+ int len;
+
+ if (i == 0)
+ if (!(s = expand_string(s)) && !expand_string_forcedfail)
+ {
+ errno = ERRNO_CHHEADER_FAIL;
+ return FALSE;
+ }
+ len = Ustrlen(s);
if (strncmpic(h->text, s, len) != 0) continue;
ss = h->text + len;
while (*ss == ' ' || *ss == '\t') ss++;
@@ -731,36 +729,40 @@ if (addr)
}
}
-/* If a string containing additional headers exists, expand it and write
-out the result. This is done last so that if it (deliberately or accidentally)
-isn't in header format, it won't mess up any other headers. An empty string
-or a forced expansion failure are noops. An added header string from a
-transport may not end with a newline; add one if it does not. */
+/* If a string containing additional headers exists it is a newline-sep
+list. Expand each item and write out the result. This is done last so that
+if it (deliberately or accidentally) isn't in header format, it won't mess
+up any other headers. An empty string or a forced expansion failure are
+noops. An added header string from a transport may not end with a newline;
+add one if it does not. */
if (add_headers)
{
- uschar *s = expand_string(add_headers);
- if (s == NULL)
- {
- if (!expand_string_forcedfail)
- { errno = ERRNO_CHHEADER_FAIL; return FALSE; }
- }
- else
- {
- int len = Ustrlen(s);
- if (len > 0)
+ int sep = '\n';
+ uschar * s;
+
+ while ((s = string_nextinlist(&add_headers, &sep, NULL, 0)))
+ if (!(s = expand_string(s)))
{
- if (!sendfn(fd, s, len, use_crlf)) return FALSE;
- if (s[len-1] != '\n' && !sendfn(fd, US"\n", 1, use_crlf))
- return FALSE;
- DEBUG(D_transport)
+ if (!expand_string_forcedfail)
+ { errno = ERRNO_CHHEADER_FAIL; return FALSE; }
+ }
+ else
+ {
+ int len = Ustrlen(s);
+ if (len > 0)
{
- debug_printf("added header line(s):\n%s", s);
- if (s[len-1] != '\n') debug_printf("\n");
- debug_printf("---\n");
+ if (!sendfn(fd, s, len, use_crlf)) return FALSE;
+ if (s[len-1] != '\n' && !sendfn(fd, US"\n", 1, use_crlf))
+ return FALSE;
+ DEBUG(D_transport)
+ {
+ debug_printf("added header line:\n%s", s);
+ if (s[len-1] != '\n') debug_printf("\n");
+ debug_printf("---\n");
+ }
}
}
- }
}
/* Separate headers from body with a blank line */