diff options
author | Todd Lyons <tlyons@exim.org> | 2014-04-15 09:53:43 -0700 |
---|---|---|
committer | Todd Lyons <tlyons@exim.org> | 2014-04-15 09:53:43 -0700 |
commit | 364e49ab87bf81774f12f8b0e21509eb51c88b71 (patch) | |
tree | 86b43906007d8a6cee2f7ad7cea22f2f8aff8a55 /src | |
parent | 3695be34bdae5e69ed8188587f03b87b6e929d42 (diff) | |
parent | 10cc8a1e4c3077eefcb37878990753d1d49cf363 (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-Base | 20 | ||||
-rw-r--r-- | src/src/dns.c | 1 | ||||
-rw-r--r-- | src/src/exim.h | 6 | ||||
-rw-r--r-- | src/src/expand.c | 9 | ||||
-rw-r--r-- | src/src/functions.h | 1 | ||||
-rw-r--r-- | src/src/lookups/dnsdb.c | 30 | ||||
-rw-r--r-- | src/src/readconf.c | 24 | ||||
-rw-r--r-- | src/src/routers/rf_get_munge_headers.c | 99 | ||||
-rw-r--r-- | src/src/string.c | 44 | ||||
-rw-r--r-- | src/src/transport.c | 76 |
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 */ |