summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2015-04-12 19:18:26 +0100
committerJeremy Harris <jgh146exb@wizmail.org>2015-04-12 19:18:26 +0100
commit9d4319dfec653f43b64562c8f31b87f2890365b2 (patch)
treed802b3bead87f49346fbac74e774f5faf61dbc74 /src
parent4e08fd50ebe820edb008a96b892a2749bbe8e72b (diff)
smtp input
Diffstat (limited to 'src')
-rw-r--r--src/src/dns.c17
-rw-r--r--src/src/exim.c4
-rw-r--r--src/src/functions.h1
-rw-r--r--src/src/globals.c2
-rw-r--r--src/src/parse.c10
-rw-r--r--src/src/smtp_in.c90
-rw-r--r--src/src/utf8.c10
7 files changed, 76 insertions, 58 deletions
diff --git a/src/src/dns.c b/src/src/dns.c
index a2f430993..f1619f4a4 100644
--- a/src/src/dns.c
+++ b/src/src/dns.c
@@ -576,6 +576,23 @@ if (previous != NULL)
return previous->data.val;
}
+#ifdef EXPERIMENTAL_INTERNATIONAL
+/* Convert all names to a-label form before doing lookup */
+ {
+ uschar * alabel;
+ uschar * errstr = NULL;
+ if ((alabel = string_domain_utf8_to_alabel(name, &errstr)), errstr)
+ {
+ DEBUG(D_dns)
+ debug_printf("DNS name '%s' utf8 conversion to alabel failed: %s", name,
+ errstr);
+ host_find_failed_syntax = TRUE;
+ return DNS_NOMATCH;
+ }
+ name = alabel;
+ }
+#endif
+
/* If configured, check the hygene of the name passed to lookup. Otherwise,
although DNS lookups may give REFUSED at the lower level, some resolvers
turn this into TRY_AGAIN, which is silly. Give a NOMATCH return, since such
diff --git a/src/src/exim.c b/src/src/exim.c
index f6d9be6ef..121c6c2e3 100644
--- a/src/src/exim.c
+++ b/src/src/exim.c
@@ -3705,6 +3705,10 @@ is equivalent to the ability to modify a setuid binary!
This needs to happen before we read the main configuration. */
init_lookup_list();
+#ifdef EXPERIMENTAL_INTERNATIONAL
+if (running_in_test_harness) smtputf8_advertise_hosts = NULL;
+#endif
+
/* Read the main runtime configuration data; this gives up if there
is a failure. It leaves the configuration file open so that the subsequent
configuration data for delivery can be read if needed. */
diff --git a/src/src/functions.h b/src/src/functions.h
index ac93c1635..fdd629228 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -422,6 +422,7 @@ extern const uschar *string_printing2(const uschar *, BOOL);
extern uschar *string_split_message(uschar *);
extern uschar *string_unprinting(uschar *);
#ifdef EXPERIMENTAL_INTERNATIONAL
+extern uschar *string_address_utf8_to_alabel(uschar *, uschar **, int *);
extern uschar *string_domain_alabel_to_utf8(const uschar *, uschar **);
extern uschar *string_domain_utf8_to_alabel(const uschar *, uschar **);
extern uschar *string_localpart_alabel_to_utf8(const uschar *, uschar **);
diff --git a/src/src/globals.c b/src/src/globals.c
index cb93a0192..2cbafcdce 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -1274,7 +1274,7 @@ int smtp_rlr_threshold = INT_MAX;
BOOL smtp_use_pipelining = FALSE;
BOOL smtp_use_size = FALSE;
#ifdef EXPERIMENTAL_INTERNATIONAL
-uschar *smtputf8_advertise_hosts = US"*";
+uschar *smtputf8_advertise_hosts = US"*"; /* overridden under test-harness */
#endif
#ifdef WITH_CONTENT_SCAN
diff --git a/src/src/parse.c b/src/src/parse.c
index ff814e738..a648f755a 100644
--- a/src/src/parse.c
+++ b/src/src/parse.c
@@ -550,9 +550,7 @@ read_addr_spec(uschar *s, uschar *t, int term, uschar **errorptr,
{
s = read_local_part(s, t, errorptr, FALSE);
if (*errorptr == NULL)
- {
if (*s != term)
- {
if (*s != '@')
*errorptr = string_sprintf("\"@\" or \".\" expected after \"%s\"", t);
else
@@ -562,8 +560,6 @@ if (*errorptr == NULL)
*domainptr = t;
s = read_domain(s, t, errorptr);
}
- }
- }
return s;
}
@@ -744,7 +740,7 @@ if (*s == '<')
while (bracket_count-- > 0) if (*s++ != '>')
{
*errorptr = (s[-1] == 0)? US"'>' missing at end of address" :
- string_sprintf("malformed address: %.32s may not follow %.*s",
+ string_sprintf("malformed address A: %.32s may not follow %.*s",
s-1, s - (uschar *)mailbox - 1, mailbox);
goto PARSE_FAILED;
}
@@ -797,7 +793,7 @@ if (*s != 0)
}
else
{
- *errorptr = string_sprintf("malformed address: %.32s may not follow %.*s",
+ *errorptr = string_sprintf("malformed address B: %.32s may not follow %.*s",
s, s - (uschar *)mailbox, mailbox);
goto PARSE_FAILED;
}
@@ -817,7 +813,7 @@ if (*end - *start > ADDRESS_MAXLENGTH)
return NULL;
}
-return (uschar *)yield;
+return yield;
/* Use goto (via the macro FAILED) to get to here from a variety of places.
We might have an empty address in a group - the caller can choose to ignore
diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
index 8086e9456..a0e44d89a 100644
--- a/src/src/smtp_in.c
+++ b/src/src/smtp_in.c
@@ -3828,10 +3828,8 @@ while (done <= 0)
(char *)mail_args < (char *)env_mail_type_list + sizeof(env_mail_type_list);
mail_args++
)
- {
if (strcmpic(name, mail_args->name) == 0)
break;
- }
if (mail_args->need_value && strcmpic(value, US"") == 0)
break;
@@ -3859,16 +3857,17 @@ while (done <= 0)
and "7BIT" as body types, but take no action. */
case ENV_MAIL_OPT_BODY:
if (accept_8bitmime) {
- if (strcmpic(value, US"8BITMIME") == 0) {
+ if (strcmpic(value, US"8BITMIME") == 0)
body_8bitmime = 8;
- } else if (strcmpic(value, US"7BIT") == 0) {
+ else if (strcmpic(value, US"7BIT") == 0)
body_8bitmime = 7;
- } else {
+ else
+ {
body_8bitmime = 0;
done = synprot_error(L_smtp_syntax_error, 501, NULL,
US"invalid data for BODY");
goto COMMAND_LOOP;
- }
+ }
DEBUG(D_receive) debug_printf("8BITMIME: %d\n", body_8bitmime);
break;
}
@@ -3880,35 +3879,43 @@ while (done <= 0)
is included only if configured in at build time. */
case ENV_MAIL_OPT_RET:
- if (dsn_advertised) {
+ if (dsn_advertised)
+ {
/* Check if RET has already been set */
- if (dsn_ret > 0) {
+ if (dsn_ret > 0)
+ {
synprot_error(L_smtp_syntax_error, 501, NULL,
US"RET can be specified once only");
goto COMMAND_LOOP;
- }
- dsn_ret = (strcmpic(value, US"HDRS") == 0)? dsn_ret_hdrs :
- (strcmpic(value, US"FULL") == 0)? dsn_ret_full : 0;
+ }
+ dsn_ret = strcmpic(value, US"HDRS") == 0
+ ? dsn_ret_hdrs
+ : strcmpic(value, US"FULL") == 0
+ ? dsn_ret_full
+ : 0;
DEBUG(D_receive) debug_printf("DSN_RET: %d\n", dsn_ret);
/* Check for invalid invalid value, and exit with error */
- if (dsn_ret == 0) {
+ if (dsn_ret == 0)
+ {
synprot_error(L_smtp_syntax_error, 501, NULL,
US"Value for RET is invalid");
goto COMMAND_LOOP;
- }
- }
+ }
+ }
break;
case ENV_MAIL_OPT_ENVID:
- if (dsn_advertised) {
+ if (dsn_advertised)
+ {
/* Check if the dsn envid has been already set */
- if (dsn_envid != NULL) {
+ if (dsn_envid != NULL)
+ {
synprot_error(L_smtp_syntax_error, 501, NULL,
US"ENVID can be specified once only");
goto COMMAND_LOOP;
- }
+ }
dsn_envid = string_copy(value);
DEBUG(D_receive) debug_printf("DSN_ENVID: %s\n", dsn_envid);
- }
+ }
break;
/* Handle the AUTH extension. If the value given is not "<>" and either
@@ -3948,34 +3955,34 @@ while (done <= 0)
switch (rc)
{
case OK:
- if (authenticated_by == NULL ||
- authenticated_by->mail_auth_condition == NULL ||
- expand_check_condition(authenticated_by->mail_auth_condition,
- authenticated_by->name, US"authenticator"))
- break; /* Accept the AUTH */
-
- ignore_msg = US"server_mail_auth_condition failed";
- if (authenticated_id != NULL)
- ignore_msg = string_sprintf("%s: authenticated ID=\"%s\"",
- ignore_msg, authenticated_id);
+ if (authenticated_by == NULL ||
+ authenticated_by->mail_auth_condition == NULL ||
+ expand_check_condition(authenticated_by->mail_auth_condition,
+ authenticated_by->name, US"authenticator"))
+ break; /* Accept the AUTH */
+
+ ignore_msg = US"server_mail_auth_condition failed";
+ if (authenticated_id != NULL)
+ ignore_msg = string_sprintf("%s: authenticated ID=\"%s\"",
+ ignore_msg, authenticated_id);
/* Fall through */
case FAIL:
- authenticated_sender = NULL;
- log_write(0, LOG_MAIN, "ignoring AUTH=%s from %s (%s)",
- value, host_and_ident(TRUE), ignore_msg);
- break;
+ authenticated_sender = NULL;
+ log_write(0, LOG_MAIN, "ignoring AUTH=%s from %s (%s)",
+ value, host_and_ident(TRUE), ignore_msg);
+ break;
/* Should only get DEFER or ERROR here. Put back terminator
overrides for error message */
default:
- value[-1] = '=';
- name[-1] = ' ';
- (void)smtp_handle_acl_fail(ACL_WHERE_MAILAUTH, rc, user_msg,
- log_msg);
- goto COMMAND_LOOP;
+ value[-1] = '=';
+ name[-1] = ' ';
+ (void)smtp_handle_acl_fail(ACL_WHERE_MAILAUTH, rc, user_msg,
+ log_msg);
+ goto COMMAND_LOOP;
}
}
break;
@@ -3990,7 +3997,7 @@ while (done <= 0)
#ifdef EXPERIMENTAL_INTERNATIONAL
case ENV_MAIL_OPT_UTF8:
if (smtputf8_advertised)
- message_smtputf8 = TRUE;
+ message_smtputf8 = allow_utf8_domains = TRUE;
break;
#endif
/* Unknown option. Stick back the terminator characters and break
@@ -4025,9 +4032,10 @@ while (done <= 0)
/* Now extract the address, first applying any SMTP-time rewriting. The
TRUE flag allows "<>" as a sender address. */
- raw_sender = ((rewrite_existflags & rewrite_smtp) != 0)?
- rewrite_one(smtp_cmd_data, rewrite_smtp, NULL, FALSE, US"",
- global_rewrite_rules) : smtp_cmd_data;
+ raw_sender = rewrite_existflags & rewrite_smtp
+ ? rewrite_one(smtp_cmd_data, rewrite_smtp, NULL, FALSE, US"",
+ global_rewrite_rules)
+ : smtp_cmd_data;
/* rfc821_domains = TRUE; << no longer needed */
raw_sender =
diff --git a/src/src/utf8.c b/src/src/utf8.c
index 9a2b8656e..32d2eaed0 100644
--- a/src/src/utf8.c
+++ b/src/src/utf8.c
@@ -78,9 +78,6 @@ size_t p_len = ucs4_len*4; /* this multiplier is pure guesswork */
uschar * res = store_get(p_len+5);
int rc;
-DEBUG(D_expand) debug_printf("l_u2a: ulen %d plen %d\n", ucs4_len, p_len);
-DEBUG(D_expand) for (rc = 0; rc < ucs4_len; rc++) debug_printf("%08x ", p[rc]);
-
res[0] = 'x'; res[1] = 'n'; res[2] = res[3] = '-';
if ((rc = punycode_encode(ucs4_len, p, NULL, &p_len, res+4)) != PUNYCODE_SUCCESS)
@@ -90,10 +87,7 @@ if ((rc = punycode_encode(ucs4_len, p, NULL, &p_len, res+4)) != PUNYCODE_SUCCESS
if (err) *err = US punycode_strerror(rc);
return NULL;
}
-DEBUG(D_expand) debug_printf("l_u2a: plen %d\n", p_len);
p_len += 4;
-DEBUG(D_expand) for (rc = 0; rc < p_len; rc++) debug_printf("%02x ", res[rc]);
-DEBUG(D_expand) debug_printf("\n");
free(p);
res[p_len] = '\0';
return res;
@@ -114,9 +108,8 @@ if (alabel[0] != 'x' || alabel[1] != 'n' || alabel[2] != '-' || alabel[3] != '-'
if (err) *err = US"bad alabel prefix";
return NULL;
}
-p_len -= 4;
-DEBUG(D_expand) debug_printf("l_a2u: plen %d\n", p_len);
+p_len -= 4;
p = (punycode_uint *) store_get((p_len+1) * sizeof(*p));
if ((rc = punycode_decode(p_len, CCS alabel+4, &p_len, p, NULL)) != PUNYCODE_SUCCESS)
@@ -124,7 +117,6 @@ if ((rc = punycode_decode(p_len, CCS alabel+4, &p_len, p, NULL)) != PUNYCODE_SUC
if (err) *err = US punycode_strerror(rc);
return NULL;
}
-DEBUG(D_expand) debug_printf("l_a2u: dlen %d\n", p_len);
s = stringprep_ucs4_to_utf8(p, p_len, NULL, &p_len);
res = string_copyn(s, p_len);