From: Jeremy Harris Date: Sat, 25 Mar 2023 23:21:15 +0000 (+0000) Subject: Experimental_XCLIENT. Bug 2702 X-Git-Tag: exim-4.97-RC0~94 X-Git-Url: https://git.exim.org/exim.git/commitdiff_plain/24cda181fb88542cf38db2beae5d0ddb37f59c5c Experimental_XCLIENT. Bug 2702 --- diff --git a/doc/doc-txt/experimental-spec.txt b/doc/doc-txt/experimental-spec.txt index aac8ca77d..5bf00a7f1 100644 --- a/doc/doc-txt/experimental-spec.txt +++ b/doc/doc-txt/experimental-spec.txt @@ -662,6 +662,37 @@ Values advertised are only noted for TLS connections and ones for which the server does not advertise TLS support. + +XCLIENT proxy support +--------------------------------------------------------------- +Per https://www.postfix.org/XCLIENT_README.html + +XCLIENT is an ESMTP extension supporting an inbound proxy. +The only client immplementation known is in Nginx +(https://nginx.org/en/docs/mail/ngx_mail_proxy_module.html) + +If compiled with EXPERIMENTAL_XCLIENT=yes :- + +As a server, Exim will advertise XCLIENT support (conditional on a new option +"hosts_xclient") and service XCLIENT commands with parameters + ADDR + NAME + PORT + LOGIN + DESTADDR + DESTPORT +A fresh HELO/EHLO is required after a succesful XCLIENT, and the usual +values are derived from that (making the HELO and PROTO paramemters redundant). + +An XCLIENT command must give both ADDR and PORT parameters if no previous +XCLIENT has succeeded in the SMTP session. + +After a success: + $proxy_session variable becomes "yes" + $proxy_local_address, $proxy_local_port have the proxy "inside" values + $proxy_external_address, $proxy_external_port have the proxy "outside" values + $sender_host_address, $sender_host_port have the remot client values + -------------------------------------------------------------- End of file -------------------------------------------------------------- diff --git a/src/OS/Makefile-Base b/src/OS/Makefile-Base index d00ab9404..71aee4d93 100644 --- a/src/OS/Makefile-Base +++ b/src/OS/Makefile-Base @@ -497,7 +497,8 @@ OBJ_EXPERIMENTAL = arc.o \ dmarc.o \ imap_utf7.o \ spf.o \ - utf8.o + utf8.o \ + xclient.o # Targets for final binaries; the main one has a build number which is # updated each time. We don't bother with that for the auxiliaries. @@ -873,6 +874,7 @@ dmarc.o: $(HDRS) pdkim/pdkim.h dmarc.h dmarc.c imap_utf7.o: $(HDRS) imap_utf7.c spf.o: $(HDRS) spf.h spf.c utf8.o: $(HDRS) utf8.c +xclient.o: $(HDRS) xclient.c # The module containing tables of available lookups, routers, auths, and # transports must be rebuilt if any of them are. However, because the makefiles diff --git a/src/scripts/MakeLinks b/src/scripts/MakeLinks index af6138063..0694af4c0 100755 --- a/src/scripts/MakeLinks +++ b/src/scripts/MakeLinks @@ -125,7 +125,7 @@ done # EXPERIMENTAL_* for f in arc.c bmi_spam.c bmi_spam.h dcc.c dcc.h dane.c dane-openssl.c \ - danessl.h imap_utf7.c spf.c spf.h srs.c srs.h utf8.c + danessl.h imap_utf7.c spf.c spf.h srs.c srs.h utf8.c xclient.c do ln -s ../src/$f $f done diff --git a/src/src/auths/xtextdecode.c b/src/src/auths/xtextdecode.c index b6a927194..edd2282d0 100644 --- a/src/src/auths/xtextdecode.c +++ b/src/src/auths/xtextdecode.c @@ -32,9 +32,9 @@ Returns: the number of bytes in the result, excluding the final zero; */ int -auth_xtextdecode(uschar *code, uschar **ptr) +auth_xtextdecode(uschar * code, uschar ** ptr) { -register int x; +int x; uschar * result = store_get(Ustrlen(code) + 1, code); *ptr = result; diff --git a/src/src/config.h.defaults b/src/src/config.h.defaults index 221705224..fb5fe3603 100644 --- a/src/src/config.h.defaults +++ b/src/src/config.h.defaults @@ -211,6 +211,7 @@ Do not put spaces between # and the 'define'. #define EXPERIMENTAL_DSN_INFO #define EXPERIMENTAL_ESMTP_LIMITS #define EXPERIMENTAL_QUEUEFILE +#define EXPERIMENTAL_XCLIENT /* For developers */ diff --git a/src/src/exim.c b/src/src/exim.c index c16beb1af..06863347d 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -1132,6 +1132,9 @@ g = string_cat(g, US"Support for:"); #ifdef EXPERIMENTAL_QUEUEFILE g = string_cat(g, US" Experimental_QUEUEFILE"); #endif +#ifdef EXPERIMENTAL_XCLIENT + g = string_cat(g, US" Experimental_XCLIENT"); +#endif g = string_cat(g, US"\n"); g = string_cat(g, US"Lookups (built-in):"); diff --git a/src/src/functions.h b/src/src/functions.h index 76392f304..aa5057a83 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -686,6 +686,11 @@ extern BOOL write_chunk(transport_ctx *, uschar *, int); extern ssize_t write_to_fd_buf(int, const uschar *, size_t); extern uschar *wrap_header(const uschar *, unsigned, unsigned, const uschar *, unsigned); +#ifdef EXPERIMENTAL_XCLIENT +extern uschar * xclient_smtp_command(uschar *, int *, BOOL *); +extern gstring * xclient_smtp_advertise_str(gstring *); +#endif + /******************************************************************************/ /* Predicate: if an address is in a tainted pool. diff --git a/src/src/globals.c b/src/src/globals.c index 539bae00e..9f4053937 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -995,11 +995,18 @@ uschar *host_lookup_msg = US""; int host_number = 0; uschar *host_number_string = NULL; uschar *host_reject_connection = NULL; -tree_node *hostlist_anchor = NULL; -int hostlist_count = 0; +uschar *hosts_connection_nolog = NULL; +#ifdef SUPPORT_PROXY +uschar *hosts_proxy = NULL; +#endif uschar *hosts_treat_as_local = NULL; uschar *hosts_require_helo = US"*"; -uschar *hosts_connection_nolog = NULL; +#ifdef EXPERIMENTAL_XCLIENT +uschar *hosts_xclient = NULL; +#endif +tree_node *hostlist_anchor = NULL; +int hostlist_count = 0; + int ignore_bounce_errors_after = 10*7*24*60*60; /* 10 weeks */ uschar *ignore_fromline_hosts = NULL; @@ -1232,8 +1239,7 @@ int process_info_len = 0; uschar *process_log_path = NULL; const uschar *process_purpose = US"fresh-exec"; -#if defined(SUPPORT_PROXY) || defined(SUPPORT_SOCKS) -uschar *hosts_proxy = NULL; +#if defined(SUPPORT_PROXY) || defined(SUPPORT_SOCKS) || defined(EXPERIMENTAL_XCLIENT) uschar *proxy_external_address = NULL; int proxy_external_port = 0; uschar *proxy_local_address = NULL; @@ -1660,5 +1666,4 @@ int warning_count = 0; const uschar *warnmsg_delay = NULL; const uschar *warnmsg_recipients = NULL; - /* End of globals.c */ diff --git a/src/src/globals.h b/src/src/globals.h index e216b9208..3a5513382 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -661,12 +661,16 @@ extern uschar *host_lookup_order; /* Order of host lookup types */ extern uschar *host_lookup_msg; /* Text for why it failed */ extern int host_number; /* For sharing spools */ extern uschar *host_number_string; /* For expanding */ -extern uschar *hosts_require_helo; /* check for HELO/EHLO before MAIL */ extern uschar *host_reject_connection; /* Reject these hosts */ -extern tree_node *hostlist_anchor; /* Tree of defined host lists */ -extern int hostlist_count; /* Number defined */ extern uschar *hosts_connection_nolog; /* Limits the logging option */ +extern uschar *hosts_require_helo; /* check for HELO/EHLO before MAIL */ extern uschar *hosts_treat_as_local; /* For routing */ +#ifdef EXPERIMENTAL_XCLIENT +extern uschar *hosts_xclient; /* Allow XCLIENT command for specified hosts */ +#endif +extern tree_node *hostlist_anchor; /* Tree of defined host lists */ +extern int hostlist_count; /* Number defined */ + extern int ignore_bounce_errors_after; /* Keep them for this time. */ extern BOOL ignore_fromline_local; /* Local SMTP ignore fromline */ @@ -828,7 +832,8 @@ extern int proxy_external_port; /* Port on remote interface of proxy */ extern uschar *proxy_local_address; /* IP of local interface of proxy */ extern int proxy_local_port; /* Port on local interface of proxy */ extern int proxy_protocol_timeout; /* Timeout for proxy negotiation */ -extern BOOL proxy_session; /* TRUE if receiving mail from valid proxy */ +extern BOOL proxy_session; /* TRUE if receiving mail from valid proxy + or sending via one */ #endif extern uschar *prvscheck_address; /* Set during prvscheck expansion item */ diff --git a/src/src/host.c b/src/src/host.c index 8d53eb3de..136ee8953 100644 --- a/src/src/host.c +++ b/src/src/host.c @@ -824,9 +824,9 @@ Returns: pointer to character string */ uschar * -host_ntoa(int type, const void *arg, uschar *buffer, int *portptr) +host_ntoa(int type, const void * arg, uschar * buffer, int * portptr) { -uschar *yield; +uschar * yield; /* The new world. It is annoying that we have to fish out the address from different places in the block, depending on what kind of address it is. It diff --git a/src/src/macro_predef.c b/src/src/macro_predef.c index 0053cb245..8fade68ca 100644 --- a/src/src/macro_predef.c +++ b/src/src/macro_predef.c @@ -205,6 +205,9 @@ due to conflicts with other common macros. */ #ifndef DISABLE_TLS_RESUME builtin_macro_create(US"_HAVE_TLS_RESUME"); #endif +#ifdef EXPERIMENTAL_XCLIENT + builtin_macro_create(US"_HAVE_XCLIENT"); +#endif #ifdef LOOKUP_LSEARCH builtin_macro_create(US"_HAVE_LOOKUP_LSEARCH"); diff --git a/src/src/macros.h b/src/src/macros.h index 36ed185ed..c55276332 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -822,7 +822,11 @@ most recent SMTP commands. SCH_NONE is "empty". */ enum { SCH_NONE, SCH_AUTH, SCH_DATA, SCH_BDAT, SCH_EHLO, SCH_ETRN, SCH_EXPN, SCH_HELO, SCH_HELP, SCH_MAIL, SCH_NOOP, SCH_QUIT, SCH_RCPT, SCH_RSET, SCH_STARTTLS, - SCH_VRFY }; + SCH_VRFY, +#ifdef EXPERIMENTAL_XCLIENT + SCH_XCLIENT, +#endif + }; /* Returns from host_find_by{name,dns}() */ diff --git a/src/src/readconf.c b/src/src/readconf.c index 3b26e87d5..7d48f085d 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -187,6 +187,9 @@ static optionlist optionlist_config[] = { #endif { "hosts_require_helo", opt_stringptr, {&hosts_require_helo} }, { "hosts_treat_as_local", opt_stringptr, {&hosts_treat_as_local} }, +#ifdef EXPERIMENTAL_XCLIENT + { "hosts_xclient", opt_stringptr, {&hosts_xclient} }, +#endif #ifdef LOOKUP_IBASE { "ibase_servers", opt_stringptr, {&ibase_servers} }, #endif @@ -399,7 +402,7 @@ static optionlist optionlist_config[] = { { "uucp_from_pattern", opt_stringptr, {&uucp_from_pattern} }, { "uucp_from_sender", opt_stringptr, {&uucp_from_sender} }, { "warn_message_file", opt_stringptr, {&warn_message_file} }, - { "write_rejectlog", opt_bool, {&write_rejectlog} } + { "write_rejectlog", opt_bool, {&write_rejectlog} }, }; #ifndef MACRO_PREDEF diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 7a45772ce..6f4ad9495 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -75,6 +75,9 @@ enum { ETRN_CMD, /* This by analogy with TURN from the RFC */ STARTTLS_CMD, /* Required by the STARTTLS RFC */ TLS_AUTH_CMD, /* auto-command at start of SSL */ +#ifdef EXPERIMENTAL_XCLIENT + XCLIENT_CMD, /* per xlexkiro implementation */ +#endif /* This is a dummy to identify the non-sync commands when pipelining */ @@ -189,14 +192,22 @@ count of non-mail commands and possibly provoke an error. tls_auth is a pseudo-command, never expected in input. It is activated on TLS startup and looks for a tls authenticator. */ -enum { CL_RSET, CL_HELO, CL_EHLO, CL_AUTH, +enum { + CL_RSET = 0, + CL_HELO, + CL_EHLO, + CL_AUTH, #ifndef DISABLE_TLS - CL_STLS, CL_TLAU, + CL_STLS, + CL_TLAU, +#endif +#ifdef EXPERIMENTAL_XCLIENT + CL_XCLI, #endif }; static smtp_cmd_list cmd_list[] = { - /* name len cmd has_arg is_mail_cmd */ + /* name len cmd has_arg is_mail_cmd */ [CL_RSET] = { "rset", sizeof("rset")-1, RSET_CMD, FALSE, FALSE }, /* First */ [CL_HELO] = { "helo", sizeof("helo")-1, HELO_CMD, TRUE, FALSE }, @@ -206,8 +217,9 @@ static smtp_cmd_list cmd_list[] = { [CL_STLS] = { "starttls", sizeof("starttls")-1, STARTTLS_CMD, FALSE, FALSE }, [CL_TLAU] = { "tls_auth", 0, TLS_AUTH_CMD, FALSE, FALSE }, #endif - -/* If you change anything above here, also fix the definitions below. */ +#ifdef EXPERIMENTAL_XCLIENT + [CL_XCLI] = { "xclient", sizeof("xclient")-1, XCLIENT_CMD, TRUE, FALSE }, +#endif { "mail from:", sizeof("mail from:")-1, MAIL_CMD, TRUE, TRUE }, { "rcpt to:", sizeof("rcpt to:")-1, RCPT_CMD, TRUE, TRUE }, @@ -241,6 +253,9 @@ uschar * smtp_names[] = [SCH_RSET] = US"RSET", [SCH_STARTTLS] = US"STARTTLS", [SCH_VRFY] = US"VRFY", +#ifdef EXPERIMENTAL_XCLIENT + [SCH_XCLIENT] = US"XCLIENT", +#endif }; static uschar *protocols_local[] = { @@ -1260,6 +1275,7 @@ return OTHER_CMD; + /************************************************* * Forced closedown of call * *************************************************/ @@ -1774,7 +1790,6 @@ while (done <= 0) bsmtp_transaction_linecount = receive_linecount; break; - /* The MAIL FROM command requires an address as an operand. All we do here is to parse it for syntactic correctness. The form "<>" is a special case which converts into an empty string. The start/end @@ -4178,7 +4193,13 @@ while (done <= 0) fl.tls_advertised = TRUE; } #endif - +#ifdef EXPERIMENTAL_XCLIENT + if (proxy_session || verify_check_host(&hosts_xclient) != FAIL) + { + g = string_catn(g, smtp_code, 3); + g = xclient_smtp_advertise_str(g); + } +#endif #ifndef DISABLE_PRDR /* Per Recipient Data Response, draft by Eric A. Hall extending RFC */ if (prdr_enable) @@ -4244,6 +4265,41 @@ while (done <= 0) toomany = FALSE; break; /* HELO/EHLO */ +#ifdef EXPERIMENTAL_XCLIENT + case XCLIENT_CMD: + { + BOOL fatal = fl.helo_seen; + uschar * errmsg; + int resp; + + HAD(SCH_XCLIENT); + smtp_mailcmd_count++; + + if ((errmsg = xclient_smtp_command(smtp_cmd_data, &resp, &fatal))) + if (fatal) + done = synprot_error(L_smtp_syntax_error, resp, NULL, errmsg); + else + { + smtp_printf("%d %s\r\n", FALSE, resp, errmsg); + log_write(0, LOG_MAIN|LOG_REJECT, "rejected XCLIENT from %s: %s", + host_and_ident(FALSE), errmsg); + } + else + { + fl.helo_seen = FALSE; /* Require another EHLO */ + smtp_code = string_sprintf("%d", resp); + + /*XXX unclear in spec. if this needs to be an ESMTP banner, + nor whether we get the original client's HELO after (or a proxy fake). + We require that we do; the following HELO/EHLO handling will set + sender_helo_name as normal. */ + + smtp_printf("%s XCLIENT success\r\n", FALSE, smtp_code); + } + break; /* XCLIENT */ + } +#endif + /* The MAIL command requires an address as an operand. All we do here is to parse it for syntactic correctness. The form "<>" is @@ -5353,6 +5409,10 @@ while (done <= 0) if (acl_smtp_etrn) smtp_printf(" ETRN", TRUE); if (acl_smtp_expn) smtp_printf(" EXPN", TRUE); if (acl_smtp_vrfy) smtp_printf(" VRFY", TRUE); +#ifdef EXPERIMENTAL_XCLIENT + if (proxy_session || verify_check_host(&hosts_xclient) != FAIL) + smtp_printf(" XCLIENT", TRUE); +#endif smtp_printf("\r\n", FALSE); break; diff --git a/src/src/xclient.c b/src/src/xclient.c new file mode 100644 index 000000000..2a8be9b0e --- /dev/null +++ b/src/src/xclient.c @@ -0,0 +1,299 @@ +/************************************************* +* Exim - an Internet mail transport agent * +*************************************************/ + +/* Copyright (c) The Exim Maintainers 2023 */ +/* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "exim.h" + +#ifdef EXPERIMENTAL_XCLIENT + +/* From https://www.postfix.org/XCLIENT_README.html I infer two generations of +protocol. The more recent one obviates the utility of the HELO attribute, since +it mandates the proxy always sending a HELO/EHLO smtp command following (a +successful) XCLIENT command, and that will carry a NELO name (which we assume, +though it isn't specified, will be the actual one presented to the proxy by the +possibly-new client). The same applies to the PROTO attribute. */ + +# define XCLIENT_V2 + +enum xclient_cmd_e { + XCLIENT_CMD_UNKNOWN, + XCLIENT_CMD_ADDR, + XCLIENT_CMD_NAME, + XCLIENT_CMD_PORT, + XCLIENT_CMD_LOGIN, + XCLIENT_CMD_DESTADDR, + XCLIENT_CMD_DESTPORT, +# ifdef XCLIENT_V1 + XCLIENT_CMD_HELO, + XCLIENT_CMD_PROTO, +# endif +}; + +struct xclient_cmd { + const uschar * str; + unsigned len; +} xclient_cmds[] = { + [XCLIENT_CMD_UNKNOWN] = { NULL }, + [XCLIENT_CMD_ADDR] = { US"ADDR", 4 }, + [XCLIENT_CMD_NAME] = { US"NAME", 4 }, + [XCLIENT_CMD_PORT] = { US"PORT", 4 }, + [XCLIENT_CMD_LOGIN] = { US"LOGIN", 5 }, + [XCLIENT_CMD_DESTADDR] = { US"DESTADDR", 8 }, + [XCLIENT_CMD_DESTPORT] = { US"DESTPORT", 8 }, +# ifdef XCLIENT_V1 + [XCLIENT_CMD_HELO] = { US"HELO", 4 }, + [XCLIENT_CMD_PROTO] = { US"PROTO", 5 }, +# endif +}; + +/************************************************* +* XCLIENT proxy implementation * +*************************************************/ + +/* Arguments: + code points to the coded string + end points to the end of coded string + ptr where to put the pointer to the result, which is in + dynamic store +Returns: the number of bytes in the result, excluding the final zero; + -1 if the input is malformed +*/ + +static int +xclient_xtextdecode(uschar * code, uschar * end, uschar ** ptr) +{ +return auth_xtextdecode(string_copyn(code, end-code), ptr); +} + +/************************************************* +* Check XCLIENT line and set sender_address * +*************************************************/ + + +/* Check the format of a XCLIENT line. +Arguments: + s the data portion of the line (already past any white space) + resp result: smtp respose code + flag input: helo seen output: fail is fatal + +Return: NULL on success, or error message +*/ + +# define XCLIENT_UNAVAIL US"[UNAVAILABLE]" +# define XCLIENT_TEMPUNAVAIL US"[TEMPUNAVAIL]" + +uschar * +xclient_smtp_command(uschar * s, int * resp, BOOL * flag) +{ +uschar * word = s; +enum { + XCLIENT_READ_COMMAND = 0, + XCLIENT_READ_VALUE, + XCLIENT_SKIP_SPACES +} state = XCLIENT_SKIP_SPACES; +enum xclient_cmd_e cmd; + +if ( !flag + && verify_check_host(&hosts_require_helo) == OK) + { + *resp = 503; + *flag = FALSE; + return US"no HELO/EHLO given"; + } + +/* If already in a proxy session, do not re-check permission. +Strictly we should avoid doing this for a Proxy-Protocol +session to avoid mixups. */ + +if(!proxy_session && verify_check_host(&hosts_xclient) == FAIL) + { + *resp = 550; + *flag = TRUE; + return US"XCLIENT command used when not advertised"; + } + +if (sender_address) + { + *resp = 503; + *flag = FALSE; + return US"mail transaction in progress"; + } + +if (!*word) + { + s = US"XCLIENT must have at least one operand"; + goto fatal_501; + } + +for (state = XCLIENT_SKIP_SPACES; *s; ) + switch (state) + { + case XCLIENT_READ_COMMAND: + { + int len; + + word = s; + while (*s && *s != '=') s++; + len = s - word; + if (!*s) + { + s = string_sprintf("XCLIENT: missing value for parameter '%.*s'", + len, word); + goto fatal_501; + } + + DEBUG(D_transport) debug_printf(" XCLIENT: cmd %.*s\n", len, word); + cmd = XCLIENT_CMD_UNKNOWN; + for (struct xclient_cmd * x = xclient_cmds + 1; + x < xclient_cmds + nelem(xclient_cmds); x++) + if (len == x->len && strncmpic(word, x->str, len) == 0) + { + cmd = x - xclient_cmds; + break; + } + if (cmd == XCLIENT_CMD_UNKNOWN) + { + s = string_sprintf("XCLIENT: unrecognised parameter '%.*s'", + len, word); + goto fatal_501; + } + state = XCLIENT_READ_VALUE; + } + break; + + case XCLIENT_READ_VALUE: + { + int old_pool = store_pool; + int len; + uschar * val; + + word = ++s; /* skip the = */ + while (*s && !isspace(*s)) s++; + len = s - word; + + DEBUG(D_transport) debug_printf(" XCLIENT: \tvalue %.*s\n", len, word); + if (len == 0) + { s = US"XCLIENT: zero-length value for param"; goto fatal_501; } + + if ( len == 13 + && ( strncmpic(word, XCLIENT_UNAVAIL, 13) == 0 + || strncmpic(word, XCLIENT_TEMPUNAVAIL, 13) == 0 + ) ) + val = NULL; + + else if ((len = xclient_xtextdecode(word, s, &val)) == -1) + { + s = string_sprintf("failed xtext decode for XCLIENT: '%.*s'", len, word); + goto fatal_501; + } + + store_pool = POOL_PERM; + switch (cmd) + { + case XCLIENT_CMD_ADDR: + proxy_local_address = sender_host_address; + sender_host_address = val ? string_copyn(val, len) : NULL; + break; + case XCLIENT_CMD_NAME: + sender_host_name = val ? string_copyn(val, len) : NULL; + break; + case XCLIENT_CMD_PORT: + proxy_local_port = sender_host_port; + sender_host_port = val ? Uatoi(val) : 0; + break; + case XCLIENT_CMD_DESTADDR: + proxy_external_address = val ? string_copyn(val, len) : NULL; + break; + case XCLIENT_CMD_DESTPORT: + proxy_external_port = val ? Uatoi(val) : 0; + break; + + case XCLIENT_CMD_LOGIN: + if (val) + { + authenticated_id = string_copyn(val, len); + sender_host_authenticated = US"xclient"; + authentication_failed = FALSE; + } + else + { + authenticated_id = NULL; + sender_host_authenticated = NULL; + } + break; + +# ifdef XCLIENT_V1 + case XCLIENT_CMD_HELO: + sender_helo_name = val ? string_copyn(val, len) : NULL; + break; + case XCLIENT_CMD_PROTO: + if (!val) + { store_pool = old_pool; s = US"missing proto for XCLIENT"; goto fatal_501; } + else if (len == 4 && strncmpic(val, US"SMTP", 4) == 0) + *esmtpflag = FALSE; /* function arg */ + else if (len == 5 && strncmpic(val, US"ESMTP", 5) == 0) + *esmtpflag = TRUE; + else + { store_pool = old_pool; s = US"bad proto for XCLIENT"; goto fatal_501; } + break; +# endif + } + store_pool = old_pool; + state = XCLIENT_SKIP_SPACES; + break; + } + + case XCLIENT_SKIP_SPACES: + while (*s && isspace (*s)) s++; + state = XCLIENT_READ_COMMAND; + break; + + default: + s = US"unhandled XCLIENT parameter type"; + goto fatal_501; + } + +if (!proxy_local_address) + { s = US"missing ADDR for XCLIENT"; goto fatal_501; } +if (!proxy_local_port) + { s = US"missing PORT for XCLIENT"; goto fatal_501; } +if (state != XCLIENT_SKIP_SPACES) + { s = US"bad state parsing XCLIENT parameters"; goto fatal_501; } + +host_build_sender_fullhost(); +proxy_session = TRUE; +*resp = 220; +return NULL; + +fatal_501: + *flag = TRUE; + *resp = 501; + return s; +} + +# undef XCLIENT_UNAVAIL +# undef XCLIENT_TEMPUNAVAIL + + +gstring * +xclient_smtp_advertise_str(gstring * g) +{ +g = string_catn(g, US"-XCLIENT ", 8); +for (int i = 1; i < nelem(xclient_cmds); i++) + { + g = string_catn(g, US" ", 1); + g = string_cat(g, xclient_cmds[i].str); + } +return string_catn(g, US"\r\n", 2); +} + + +#endif /*EXPERIMENTAL_XCLIENT*/ + +/* vi: aw ai sw=2 +*/ +/* End of xclient.c */ diff --git a/test/confs/4032 b/test/confs/4032 new file mode 100644 index 000000000..9dbe36b9c --- /dev/null +++ b/test/confs/4032 @@ -0,0 +1,41 @@ +# Exim test configuration 4032 +# XCLIENT proxy + +.ifdef OPTION +.include DIR/aux-var/tls_conf_prefix +.else +.include DIR/aux-var/std_conf_prefix +.endif + +primary_hostname = myhost.test.ex +hosts_xclient = HOSTIPV4 +queue_only + +# ----- Main settings ----- + +log_selector = +proxy +incoming_port + +acl_smtp_rcpt = r_acl + + +begin acl + +r_acl: + accept + logwrite = tls session: ${if def:tls_in_cipher {yes}{no}} + logwrite = proxy session: $proxy_session + logwrite = local [$received_ip_address]:$received_port + logwrite = proxy internal [$proxy_local_address]:$proxy_local_port + logwrite = proxy external [$proxy_external_address]:$proxy_external_port + logwrite = remote [$sender_host_address]:$sender_host_port + + +# ----- Routers ----- + +begin routers + +dump: + driver = redirect + data = :blackhole: + +# End diff --git a/test/confs/4033 b/test/confs/4033 new file mode 120000 index 000000000..06b9789ad --- /dev/null +++ b/test/confs/4033 @@ -0,0 +1 @@ +4032 \ No newline at end of file diff --git a/test/confs/4034 b/test/confs/4034 new file mode 120000 index 000000000..06b9789ad --- /dev/null +++ b/test/confs/4034 @@ -0,0 +1 @@ +4032 \ No newline at end of file diff --git a/test/log/4032 b/test/log/4032 new file mode 100644 index 000000000..b02c0c263 --- /dev/null +++ b/test/log/4032 @@ -0,0 +1,27 @@ + +******** SERVER ******** +1999-03-02 09:44:33 exim x.yz daemon started: pid=p1234, no queue runs, listening for SMTP on port PORT_D +1999-03-02 09:44:33 tls session: no +1999-03-02 09:44:33 proxy session: no +1999-03-02 09:44:33 local [127.0.0.1]:1113 +1999-03-02 09:44:33 proxy internal []:0 +1999-03-02 09:44:33 proxy external []:0 +1999-03-02 09:44:33 remote [127.0.0.1]:1114 +1999-03-02 09:44:33 10HmaX-0005vi-00 <= a@test.ex H=(plainclient) [127.0.0.1]:1114 P=esmtp S=sss +1999-03-02 09:44:33 tls session: no +1999-03-02 09:44:33 proxy session: yes +1999-03-02 09:44:33 local [ip4.ip4.ip4.ip4]:1113 +1999-03-02 09:44:33 proxy internal [ip4.ip4.ip4.ip4]:1115 +1999-03-02 09:44:33 proxy external [10.42.42.42]:1116 +1999-03-02 09:44:33 remote [127.0.0.2]:1117 +1999-03-02 09:44:33 10HmaY-0005vi-00 <= c@test.ex H=proxylookedupname.net (clienthelo) [127.0.0.2]:1117 P=esmtpa A=xclient:hisloginname PRX=ip4.ip4.ip4.ip4 S=sss +1999-03-02 09:44:33 tls session: no +1999-03-02 09:44:33 proxy session: yes +1999-03-02 09:44:33 local [ip4.ip4.ip4.ip4]:1113 +1999-03-02 09:44:33 proxy internal [127.0.0.2]:1117 +1999-03-02 09:44:33 proxy external [10.42.42.42]:1116 +1999-03-02 09:44:33 remote [127.0.0.3]:1111 +1999-03-02 09:44:33 10HmaZ-0005vi-00 <= c2@test.ex H=(anotherhelo) [127.0.0.3]:1111 P=esmtp PRX=127.0.0.2 S=sss +1999-03-02 09:44:33 rejected XCLIENT from (anotherhelo) [127.0.0.3]:1111: mail transaction in progress +1999-03-02 09:44:33 rejected MAIL from miss.ehlo.after.xclient (anotherhelo) [127.0.0.3]:1111: no HELO/EHLO given +1999-03-02 09:44:33 SMTP call from (xclientproxy) [ip4.ip4.ip4.ip4]:1112 dropped: too many syntax or protocol errors (last command was "XCLIENT SIXSIX=", C=EHLO,XCLIENT,XCLIENT,XCLIENT,XCLIENT) diff --git a/test/log/4034 b/test/log/4034 new file mode 100644 index 000000000..9ec307501 --- /dev/null +++ b/test/log/4034 @@ -0,0 +1,29 @@ + +******** SERVER ******** +1999-03-02 09:44:33 Warning: No server certificate defined; will use a selfsigned one. + Suggested action: either install a certificate or change tls_advertise_hosts option +1999-03-02 09:44:33 exim x.yz daemon started: pid=p1234, no queue runs, listening for SMTP on port PORT_D +1999-03-02 09:44:33 tls session: yes +1999-03-02 09:44:33 proxy session: no +1999-03-02 09:44:33 local [127.0.0.1]:1113 +1999-03-02 09:44:33 proxy internal []:0 +1999-03-02 09:44:33 proxy external []:0 +1999-03-02 09:44:33 remote [127.0.0.1]:1114 +1999-03-02 09:44:33 10HmaX-0005vi-00 <= a@test.ex H=(plainclient) [127.0.0.1]:1114 P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss +1999-03-02 09:44:33 tls session: yes +1999-03-02 09:44:33 proxy session: yes +1999-03-02 09:44:33 local [ip4.ip4.ip4.ip4]:1113 +1999-03-02 09:44:33 proxy internal [ip4.ip4.ip4.ip4]:1115 +1999-03-02 09:44:33 proxy external [10.42.42.42]:1116 +1999-03-02 09:44:33 remote [127.0.0.2]:1117 +1999-03-02 09:44:33 10HmaY-0005vi-00 <= c@test.ex H=proxylookedupname.net (clienthelo) [127.0.0.2]:1117 P=esmtpsa X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no A=xclient:hisloginname PRX=ip4.ip4.ip4.ip4 S=sss +1999-03-02 09:44:33 tls session: yes +1999-03-02 09:44:33 proxy session: yes +1999-03-02 09:44:33 local [ip4.ip4.ip4.ip4]:1113 +1999-03-02 09:44:33 proxy internal [127.0.0.2]:1117 +1999-03-02 09:44:33 proxy external [10.42.42.42]:1116 +1999-03-02 09:44:33 remote [127.0.0.3]:1111 +1999-03-02 09:44:33 10HmaZ-0005vi-00 <= c2@test.ex H=(anotherhelo) [127.0.0.3]:1111 P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no PRX=127.0.0.2 S=sss +1999-03-02 09:44:33 rejected XCLIENT from (anotherhelo) [127.0.0.3]:1111: mail transaction in progress +1999-03-02 09:44:33 rejected MAIL from miss.ehlo.after.xclient (anotherhelo) [127.0.0.3]:1111: no HELO/EHLO given +1999-03-02 09:44:33 SMTP call from (xclientproxy) [ip4.ip4.ip4.ip4]:1112 dropped: too many syntax or protocol errors (last command was "XCLIENT SIXSIX=", C=EHLO,STARTTLS,EHLO,XCLIENT,XCLIENT,XCLIENT,XCLIENT) diff --git a/test/rejectlog/4032 b/test/rejectlog/4032 new file mode 100644 index 000000000..96c50b75e --- /dev/null +++ b/test/rejectlog/4032 @@ -0,0 +1,5 @@ + +******** SERVER ******** +1999-03-02 09:44:33 rejected XCLIENT from (anotherhelo) [127.0.0.3]:1111: mail transaction in progress +1999-03-02 09:44:33 rejected MAIL from miss.ehlo.after.xclient (anotherhelo) [127.0.0.3]:1111: no HELO/EHLO given +1999-03-02 09:44:33 SMTP call from (xclientproxy) [ip4.ip4.ip4.ip4]:1112 dropped: too many syntax or protocol errors (last command was "XCLIENT SIXSIX=", C=EHLO,XCLIENT,XCLIENT,XCLIENT,XCLIENT) diff --git a/test/rejectlog/4034 b/test/rejectlog/4034 new file mode 100644 index 000000000..de477a533 --- /dev/null +++ b/test/rejectlog/4034 @@ -0,0 +1,5 @@ + +******** SERVER ******** +1999-03-02 09:44:33 rejected XCLIENT from (anotherhelo) [127.0.0.3]:1111: mail transaction in progress +1999-03-02 09:44:33 rejected MAIL from miss.ehlo.after.xclient (anotherhelo) [127.0.0.3]:1111: no HELO/EHLO given +1999-03-02 09:44:33 SMTP call from (xclientproxy) [ip4.ip4.ip4.ip4]:1112 dropped: too many syntax or protocol errors (last command was "XCLIENT SIXSIX=", C=EHLO,STARTTLS,EHLO,XCLIENT,XCLIENT,XCLIENT,XCLIENT) diff --git a/test/runtest b/test/runtest index 8d96e13bd..53e12d412 100755 --- a/test/runtest +++ b/test/runtest @@ -1387,6 +1387,9 @@ RESET_AFTER_EXTRA_LINE_READ: } next if / in limits_advertise_hosts?\? no \(matched "!\*"\)/; + # Experimental_XCLIENT + next if / in hosts_xclient?\? no \(option unset\)/; + # TCP Fast Open next if /^(ppppp )?setsockopt FASTOPEN: Network Error/; diff --git a/test/scripts/4032-xclient/4032 b/test/scripts/4032-xclient/4032 new file mode 100644 index 000000000..fa0d0b8c3 --- /dev/null +++ b/test/scripts/4032-xclient/4032 @@ -0,0 +1,140 @@ +# XCLIENT proxy on inbound smtp +# +munge loopback +# +exim -bd -DSERVER=server -oX PORT_D +**** +# +### (1) non-prox plain receive (not advertised) (2) XCLIENT refules when not advertised +client 127.0.0.1 PORT_D +??? 220 +EHLO plainclient +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250 HELP +MAIL FROM: +??? 250 +RCPT TO: +??? 250 +DATA +??? 354 +Subject: test + +body +. +??? 250 +XCLIENT NAME=proxylookedupname.net ADDR=127.0.0.2 PORT=4242 +??? 550 +QUIT +??? 221 +**** +# +### receive, (1) fully loaded (2) new conn (3) bad: transaction in progress (4) bad: missing EHLO after XCLIENT +client HOSTIPV4 PORT_D +??? 220 +EHLO xclientproxy +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-XCLIENT +??? 250 HELP +XCLIENT NAME=proxylookedupname.net ADDR=127.0.0.2 PORT=4242 DESTADDR=10.42.42.42 DESTPORT=25 LOGIN=hisloginname +??? 220 +EHLO clienthelo +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-XCLIENT +??? 250 HELP +MAIL FROM: +??? 250 +RCPT TO: +??? 250 +DATA +??? 354 +Subject: test + +body +. +??? 250 +XCLIENT NAME=[TEMPUNAVAIL] ADDR=127.0.0.3 PORT=4243 LOGIN=[UNAVAILABLE] +??? 220 +EHLO anotherhelo +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-XCLIENT +??? 250 HELP +MAIL FROM: +??? 250 +RCPT TO: +??? 250 +DATA +??? 354 +Subject: test + +body +. +??? 250 +MAIL FROM: +??? 250 +XCLIENT NAME=bad.time.for.xclient +??? 503 +RSET +??? 250 +XCLIENT NAME=miss.ehlo.after.xclient +??? 220 +MAIL FROM: +??? 503 +QUIT +??? 221 +**** +# +### (5) no operands to XCLIENT (6,7) unrecognised operands +client HOSTIPV4 PORT_D +??? 220 +EHLO xclientproxy +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-XCLIENT +??? 250 HELP +XCLIENT +??? 501 +XCLIENT NONO= +??? 501 +XCLIENT NAMEfoobar= +??? 501 +XCLIENT SIXSIX= +??? 501- +??? 501 Too many +???* +**** +# +### (7) operand with zero-len value (8) operand with no value +client HOSTIPV4 PORT_D +??? 220 +EHLO xclientproxy +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-XCLIENT +??? 250 HELP +XCLIENT NAME= +??? 501 +XCLIENT NAME +??? 501 +**** +# +# +killdaemon +no_msglog_check +no_stdout_check +no_stderr_check diff --git a/test/scripts/4032-xclient/4033 b/test/scripts/4032-xclient/4033 new file mode 100644 index 000000000..f3a4ecdeb --- /dev/null +++ b/test/scripts/4032-xclient/4033 @@ -0,0 +1,62 @@ +# XCLIENT proxy on inbound -bh +# +### (1) non-prox plain receive (not advertised) (2) XCLIENT refules when not advertised +exim -bh 127.0.0.1.4241 -oMi 127.0.0.1 +EHLO plainclient +MAIL FROM: +RCPT TO: +DATA +Subject: test + +body +. +XCLIENT NAME=proxylookedupname.net ADDR=127.0.0.2 PORT=4242 +QUIT +**** +# +### receive, (1) fully loaded (2) new conn (3) bad: transaction in progress +exim -bh HOSTIPV4.4241 -oMi HOSTIPV4 +EHLO xclientproxy +XCLIENT NAME=proxylookedupname.net ADDR=127.0.0.2 PORT=4242 DESTADDR=10.42.42.42 DESTPORT=25 LOGIN=hisloginname +EHLO clienthelo +MAIL FROM: +RCPT TO: +DATA +Subject: test + +body +. +XCLIENT NAME=[TEMPUNAVAIL] ADDR=127.0.0.3 PORT=4243 LOGIN=[UNAVAILABLE] +EHLO anotherhelo +MAIL FROM: +RCPT TO: +DATA +Subject: test + +body +. +MAIL FROM: +XCLIENT NAME=bad.time.for.xclient +RSET +XCLIENT NAME=miss.ehlo.after.xclient +MAIL FROM: +QUIT +**** +# +### (4) no operands to XCLIENT (5,6) unrecognised operands +exim -bh HOSTIPV4.4241 -oMi HOSTIPV4 +EHLO xclientproxy +XCLIENT +XCLIENT NONO= +XCLIENT NAMEfoobar= +XCLIENT SIXSIX= +**** +# +### (7) operand with zero-len value (8) operand with no value +exim -bh HOSTIPV4.4241 -oMi HOSTIPV4 +EHLO xclientproxy +XCLIENT NAME= +XCLIENT NAME +**** +# +no_stderr_check diff --git a/test/scripts/4032-xclient/REQUIRES b/test/scripts/4032-xclient/REQUIRES new file mode 100644 index 000000000..5f4d76eed --- /dev/null +++ b/test/scripts/4032-xclient/REQUIRES @@ -0,0 +1 @@ +support Experimental_XCLIENT diff --git a/test/scripts/4034-xclient-tls/4034 b/test/scripts/4034-xclient-tls/4034 new file mode 100644 index 000000000..c8a4f10c4 --- /dev/null +++ b/test/scripts/4034-xclient-tls/4034 @@ -0,0 +1,179 @@ +# XCLIENT under TLS +# +munge loopback +# +exim -bd -DSERVER=server -DOPTION -oX PORT_D +**** +# +### (1) non-prox plain receive (not advertised) (2) XCLIENT refusal when not advertised +client-anytls 127.0.0.1 PORT_D +??? 220 +EHLO plainclient +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-STARTTLS +??? 250 HELP +STARTTLS +??? 220 +EHLO plainclient +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250 HELP +MAIL FROM: +??? 250 +RCPT TO: +??? 250 +DATA +??? 354 +Subject: test + +body +. +??? 250 +XCLIENT NAME=proxylookedupname.net ADDR=127.0.0.2 PORT=4242 +??? 550 +QUIT +??? 221 +**** +# +### receive, (1) fully loaded (2) new conn (3) bad: transaction in progress (4) bad: missing EHLO after XCLIENT +client-anytls HOSTIPV4 PORT_D +??? 220 +EHLO xclientproxy +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-STARTTLS +??? 250-XCLIENT +??? 250 HELP +STARTTLS +??? 220 +EHLO xclientproxy +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-XCLIENT +??? 250 HELP +XCLIENT NAME=proxylookedupname.net ADDR=127.0.0.2 PORT=4242 DESTADDR=10.42.42.42 DESTPORT=25 LOGIN=hisloginname +??? 220 +EHLO clienthelo +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-XCLIENT +??? 250 HELP +MAIL FROM: +??? 250 +RCPT TO: +??? 250 +DATA +??? 354 +Subject: test + +body +. +??? 250 +XCLIENT NAME=[TEMPUNAVAIL] ADDR=127.0.0.3 PORT=4243 LOGIN=[UNAVAILABLE] +??? 220 +EHLO anotherhelo +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-XCLIENT +??? 250 HELP +MAIL FROM: +??? 250 +RCPT TO: +??? 250 +DATA +??? 354 +Subject: test + +body +. +??? 250 +MAIL FROM: +??? 250 +XCLIENT NAME=bad.time.for.xclient +??? 503 +RSET +??? 250 +XCLIENT NAME=miss.ehlo.after.xclient +??? 220 +MAIL FROM: +??? 503 +QUIT +??? 221 +**** +# +### (5) no operands to XCLIENT (6,7) unrecognised operands +client-anytls HOSTIPV4 PORT_D +??? 220 +EHLO xclientproxy +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-STARTTLS +??? 250-XCLIENT +??? 250 HELP +STARTTLS +??? 220 +EHLO xclientproxy +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-XCLIENT +??? 250 HELP +XCLIENT +??? 501 +XCLIENT NONO= +??? 501 +XCLIENT NAMEfoobar= +??? 501 +XCLIENT SIXSIX= +??? 501- +??? 501 Too many +???* +**** +# +### (7) operand with zero-len value (8) operand with no value +client-anytls HOSTIPV4 PORT_D +??? 220 +EHLO xclientproxy +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-STARTTLS +??? 250-XCLIENT +??? 250 HELP +STARTTLS +??? 220 +EHLO xclientproxy +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-XCLIENT +??? 250 HELP +XCLIENT NAME= +??? 501 +XCLIENT NAME +??? 501 +**** +# +# +killdaemon +no_msglog_check +no_stdout_check +no_stderr_check diff --git a/test/scripts/4034-xclient-tls/REQUIRES b/test/scripts/4034-xclient-tls/REQUIRES new file mode 100644 index 000000000..4361afb13 --- /dev/null +++ b/test/scripts/4034-xclient-tls/REQUIRES @@ -0,0 +1,2 @@ +support Experimental_XCLIENT +feature _HAVE_TLS diff --git a/test/stdout/4032 b/test/stdout/4032 new file mode 100644 index 000000000..41c916c0e --- /dev/null +++ b/test/stdout/4032 @@ -0,0 +1,199 @@ +### (1) non-prox plain receive (not advertised) (2) XCLIENT refules when not advertised +Connecting to 127.0.0.1 port 1225 ... connected +??? 220 +<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +>>> EHLO plainclient +??? 250- +<<< 250-myhost.test.ex Hello plainclient [IP_LOOPBACK_ADDR] +??? 250-SIZE +<<< 250-SIZE 52428800 +??? 250-8BITMIME +<<< 250-8BITMIME +??? 250-PIPELINING +<<< 250-PIPELINING +??? 250 HELP +<<< 250 HELP +>>> MAIL FROM: +??? 250 +<<< 250 OK +>>> RCPT TO: +??? 250 +<<< 250 Accepted +>>> DATA +??? 354 +<<< 354 Enter message, ending with "." on a line by itself +>>> Subject: test +>>> +>>> body +>>> . +??? 250 +<<< 250 OK id=10HmaX-0005vi-00 +>>> XCLIENT NAME=proxylookedupname.net ADDR=127.0.0.2 PORT=4242 +??? 550 +<<< 550 XCLIENT command used when not advertised +>>> QUIT +??? 221 +<<< 221 myhost.test.ex closing connection +End of script +### receive, (1) fully loaded (2) new conn (3) bad: transaction in progress (4) bad: missing EHLO after XCLIENT +Connecting to ip4.ip4.ip4.ip4 port 1225 ... connected +??? 220 +<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +>>> EHLO xclientproxy +??? 250- +<<< 250-myhost.test.ex Hello xclientproxy [ip4.ip4.ip4.ip4] +??? 250-SIZE +<<< 250-SIZE 52428800 +??? 250-8BITMIME +<<< 250-8BITMIME +??? 250-PIPELINING +<<< 250-PIPELINING +??? 250-XCLIENT +<<< 250-XCLIENT ADDR NAME PORT LOGIN DESTADDR DESTPORT +??? 250 HELP +<<< 250 HELP +>>> XCLIENT NAME=proxylookedupname.net ADDR=127.0.0.2 PORT=4242 DESTADDR=10.42.42.42 DESTPORT=25 LOGIN=hisloginname +??? 220 +<<< 220 XCLIENT success +>>> EHLO clienthelo +??? 250- +<<< 250-myhost.test.ex Hello proxylookedupname.net [127.0.0.2] +??? 250-SIZE +<<< 250-SIZE 52428800 +??? 250-8BITMIME +<<< 250-8BITMIME +??? 250-PIPELINING +<<< 250-PIPELINING +??? 250-XCLIENT +<<< 250-XCLIENT ADDR NAME PORT LOGIN DESTADDR DESTPORT +??? 250 HELP +<<< 250 HELP +>>> MAIL FROM: +??? 250 +<<< 250 OK +>>> RCPT TO: +??? 250 +<<< 250 Accepted +>>> DATA +??? 354 +<<< 354 Enter message, ending with "." on a line by itself +>>> Subject: test +>>> +>>> body +>>> . +??? 250 +<<< 250 OK id=10HmaY-0005vi-00 +>>> XCLIENT NAME=[TEMPUNAVAIL] ADDR=127.0.0.3 PORT=4243 LOGIN=[UNAVAILABLE] +??? 220 +<<< 220 XCLIENT success +>>> EHLO anotherhelo +??? 250- +<<< 250-myhost.test.ex Hello anotherhelo [127.0.0.3] +??? 250-SIZE +<<< 250-SIZE 52428800 +??? 250-8BITMIME +<<< 250-8BITMIME +??? 250-PIPELINING +<<< 250-PIPELINING +??? 250-XCLIENT +<<< 250-XCLIENT ADDR NAME PORT LOGIN DESTADDR DESTPORT +??? 250 HELP +<<< 250 HELP +>>> MAIL FROM: +??? 250 +<<< 250 OK +>>> RCPT TO: +??? 250 +<<< 250 Accepted +>>> DATA +??? 354 +<<< 354 Enter message, ending with "." on a line by itself +>>> Subject: test +>>> +>>> body +>>> . +??? 250 +<<< 250 OK id=10HmaZ-0005vi-00 +>>> MAIL FROM: +??? 250 +<<< 250 OK +>>> XCLIENT NAME=bad.time.for.xclient +??? 503 +<<< 503 mail transaction in progress +>>> RSET +??? 250 +<<< 250 Reset OK +>>> XCLIENT NAME=miss.ehlo.after.xclient +??? 220 +<<< 220 XCLIENT success +>>> MAIL FROM: +??? 503 +<<< 503 HELO or EHLO required +>>> QUIT +??? 221 +<<< 221 myhost.test.ex closing connection +End of script +### (5) no operands to XCLIENT (6,7) unrecognised operands +Connecting to ip4.ip4.ip4.ip4 port 1225 ... connected +??? 220 +<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +>>> EHLO xclientproxy +??? 250- +<<< 250-myhost.test.ex Hello xclientproxy [ip4.ip4.ip4.ip4] +??? 250-SIZE +<<< 250-SIZE 52428800 +??? 250-8BITMIME +<<< 250-8BITMIME +??? 250-PIPELINING +<<< 250-PIPELINING +??? 250-XCLIENT +<<< 250-XCLIENT ADDR NAME PORT LOGIN DESTADDR DESTPORT +??? 250 HELP +<<< 250 HELP +>>> XCLIENT +??? 501 +<<< 501 XCLIENT must have at least one operand +>>> XCLIENT NONO= +??? 501 +<<< 501 XCLIENT: unrecognised parameter 'NONO' +>>> XCLIENT NAMEfoobar= +??? 501 +<<< 501 XCLIENT: unrecognised parameter 'NAMEfoobar' +>>> XCLIENT SIXSIX= +??? 501- +<<< 501-XCLIENT: unrecognised parameter 'SIXSIX' +??? 501 Too many +<<< 501 Too many syntax or protocol errors +???* +Expected EOF read +End of script +### (7) operand with zero-len value (8) operand with no value +Connecting to ip4.ip4.ip4.ip4 port 1225 ... connected +??? 220 +<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +>>> EHLO xclientproxy +??? 250- +<<< 250-myhost.test.ex Hello xclientproxy [ip4.ip4.ip4.ip4] +??? 250-SIZE +<<< 250-SIZE 52428800 +??? 250-8BITMIME +<<< 250-8BITMIME +??? 250-PIPELINING +<<< 250-PIPELINING +??? 250-XCLIENT +<<< 250-XCLIENT ADDR NAME PORT LOGIN DESTADDR DESTPORT +??? 250 HELP +<<< 250 HELP +>>> XCLIENT NAME= +??? 501 +<<< 501 XCLIENT: zero-length value for param +>>> XCLIENT NAME +??? 501 +<<< 501 XCLIENT: missing value for parameter 'NAME' +End of script + +******** SERVER ******** +### (1) non-prox plain receive (not advertised) (2) XCLIENT refules when not advertised +### receive, (1) fully loaded (2) new conn (3) bad: transaction in progress (4) bad: missing EHLO after XCLIENT +### (5) no operands to XCLIENT (6,7) unrecognised operands +### (7) operand with zero-len value (8) operand with no value diff --git a/test/stdout/4033 b/test/stdout/4033 new file mode 100644 index 000000000..546ca8b1a --- /dev/null +++ b/test/stdout/4033 @@ -0,0 +1,108 @@ +### (1) non-prox plain receive (not advertised) (2) XCLIENT refules when not advertised + +**** SMTP testing session as if from host 127.0.0.1 +**** but without any ident (RFC 1413) callback. +**** This is not for real! + +220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +250-myhost.test.ex Hello plainclient [127.0.0.1] +250-SIZE 52428800 +250-8BITMIME +250-PIPELINING +250 HELP +250 OK +250 Accepted +354 Enter message, ending with "." on a line by itself +250 OK id=10HmaX-0005vi-00 + +**** SMTP testing: that is not a real message id! + +550 XCLIENT command used when not advertised +221 myhost.test.ex closing connection +### receive, (1) fully loaded (2) new conn (3) bad: transaction in progress + +**** SMTP testing session as if from host ip4.ip4.ip4.ip4 +**** but without any ident (RFC 1413) callback. +**** This is not for real! + +220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +250-myhost.test.ex Hello xclientproxy [ip4.ip4.ip4.ip4] +250-SIZE 52428800 +250-8BITMIME +250-PIPELINING +250-XCLIENT ADDR NAME PORT LOGIN DESTADDR DESTPORT +250 HELP +220 XCLIENT success +250-myhost.test.ex Hello proxylookedupname.net [127.0.0.2] +250-SIZE 52428800 +250-8BITMIME +250-PIPELINING +250-XCLIENT ADDR NAME PORT LOGIN DESTADDR DESTPORT +250 HELP +250 OK +250 Accepted +354 Enter message, ending with "." on a line by itself +250 OK id=10HmaY-0005vi-00 + +**** SMTP testing: that is not a real message id! + +220 XCLIENT success +250-myhost.test.ex Hello anotherhelo [127.0.0.3] +250-SIZE 52428800 +250-8BITMIME +250-PIPELINING +250-XCLIENT ADDR NAME PORT LOGIN DESTADDR DESTPORT +250 HELP +250 OK +250 Accepted +354 Enter message, ending with "." on a line by itself +250 OK id=10HmaZ-0005vi-00 + +**** SMTP testing: that is not a real message id! + +250 OK +503 mail transaction in progress +250 Reset OK +220 XCLIENT success +503 HELO or EHLO required +221 myhost.test.ex closing connection +### (4) no operands to XCLIENT (5,6) unrecognised operands + +**** SMTP testing session as if from host ip4.ip4.ip4.ip4 +**** but without any ident (RFC 1413) callback. +**** This is not for real! + +220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +250-myhost.test.ex Hello xclientproxy [ip4.ip4.ip4.ip4] +250-SIZE 52428800 +250-8BITMIME +250-PIPELINING +250-XCLIENT ADDR NAME PORT LOGIN DESTADDR DESTPORT +250 HELP +501 XCLIENT must have at least one operand +501 XCLIENT: unrecognised parameter 'NONO' +501 XCLIENT: unrecognised parameter 'NAMEfoobar' +501-XCLIENT: unrecognised parameter 'SIXSIX' +501 Too many syntax or protocol errors +### (7) operand with zero-len value (8) operand with no value + +**** SMTP testing session as if from host ip4.ip4.ip4.ip4 +**** but without any ident (RFC 1413) callback. +**** This is not for real! + +220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +250-myhost.test.ex Hello xclientproxy [ip4.ip4.ip4.ip4] +250-SIZE 52428800 +250-8BITMIME +250-PIPELINING +250-XCLIENT ADDR NAME PORT LOGIN DESTADDR DESTPORT +250 HELP +501 XCLIENT: zero-length value for param +501 XCLIENT: missing value for parameter 'NAME' +421 myhost.test.ex lost input connection + +******** SERVER ******** +### (1) non-prox plain receive (not advertised) (2) XCLIENT refules when not advertised +### receive, (1) fully loaded (2) new conn (3) bad: transaction in progress +### (4) no operands to XCLIENT (5,6) unrecognised operands +### (7) operand with zero-len value (8) operand with no value