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
--------------------------------------------------------------
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.
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
# 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
*/
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;
#define EXPERIMENTAL_DSN_INFO
#define EXPERIMENTAL_ESMTP_LIMITS
#define EXPERIMENTAL_QUEUEFILE
+#define EXPERIMENTAL_XCLIENT
/* For developers */
#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):");
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.
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;
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;
const uschar *warnmsg_delay = NULL;
const uschar *warnmsg_recipients = NULL;
-
/* End of globals.c */
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 */
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 */
*/
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
#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");
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}() */
#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
{ "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
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 */
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 },
[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 },
[SCH_RSET] = US"RSET",
[SCH_STARTTLS] = US"STARTTLS",
[SCH_VRFY] = US"VRFY",
+#ifdef EXPERIMENTAL_XCLIENT
+ [SCH_XCLIENT] = US"XCLIENT",
+#endif
};
static uschar *protocols_local[] = {
+
/*************************************************
* Forced closedown of call *
*************************************************/
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
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)
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
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;
--- /dev/null
+/*************************************************
+* 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 */
--- /dev/null
+# 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
--- /dev/null
+4032
\ No newline at end of file
--- /dev/null
+4032
\ No newline at end of file
--- /dev/null
+
+******** 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)
--- /dev/null
+
+******** 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)
--- /dev/null
+
+******** 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)
--- /dev/null
+
+******** 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)
}
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/;
--- /dev/null
+# 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:<a@test.ex>
+??? 250
+RCPT TO:<b@test.ex>
+??? 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:<c@test.ex>
+??? 250
+RCPT TO:<d@test.ex>
+??? 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:<c2@test.ex>
+??? 250
+RCPT TO:<d2@test.ex>
+??? 250
+DATA
+??? 354
+Subject: test
+
+body
+.
+??? 250
+MAIL FROM:<c2@test.ex>
+??? 250
+XCLIENT NAME=bad.time.for.xclient
+??? 503
+RSET
+??? 250
+XCLIENT NAME=miss.ehlo.after.xclient
+??? 220
+MAIL FROM:<bad@test.ex>
+??? 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
--- /dev/null
+# 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:<a@test.ex>
+RCPT TO:<b@test.ex>
+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:<c@test.ex>
+RCPT TO:<d@test.ex>
+DATA
+Subject: test
+
+body
+.
+XCLIENT NAME=[TEMPUNAVAIL] ADDR=127.0.0.3 PORT=4243 LOGIN=[UNAVAILABLE]
+EHLO anotherhelo
+MAIL FROM:<c2@test.ex>
+RCPT TO:<d2@test.ex>
+DATA
+Subject: test
+
+body
+.
+MAIL FROM:<c2@test.ex>
+XCLIENT NAME=bad.time.for.xclient
+RSET
+XCLIENT NAME=miss.ehlo.after.xclient
+MAIL FROM:<bad@test.ex>
+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
--- /dev/null
+support Experimental_XCLIENT
--- /dev/null
+# 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:<a@test.ex>
+??? 250
+RCPT TO:<b@test.ex>
+??? 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:<c@test.ex>
+??? 250
+RCPT TO:<d@test.ex>
+??? 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:<c2@test.ex>
+??? 250
+RCPT TO:<d2@test.ex>
+??? 250
+DATA
+??? 354
+Subject: test
+
+body
+.
+??? 250
+MAIL FROM:<c2@test.ex>
+??? 250
+XCLIENT NAME=bad.time.for.xclient
+??? 503
+RSET
+??? 250
+XCLIENT NAME=miss.ehlo.after.xclient
+??? 220
+MAIL FROM:<bad@test.ex>
+??? 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
--- /dev/null
+support Experimental_XCLIENT
+feature _HAVE_TLS
--- /dev/null
+### (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:<a@test.ex>
+??? 250
+<<< 250 OK
+>>> RCPT TO:<b@test.ex>
+??? 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:<c@test.ex>
+??? 250
+<<< 250 OK
+>>> RCPT TO:<d@test.ex>
+??? 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:<c2@test.ex>
+??? 250
+<<< 250 OK
+>>> RCPT TO:<d2@test.ex>
+??? 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:<c2@test.ex>
+??? 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:<bad@test.ex>
+??? 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
--- /dev/null
+### (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\r
+250-myhost.test.ex Hello plainclient [127.0.0.1]\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmaX-0005vi-00\r
+
+**** SMTP testing: that is not a real message id!
+
+550 XCLIENT command used when not advertised\r
+221 myhost.test.ex closing connection\r
+### 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\r
+250-myhost.test.ex Hello xclientproxy [ip4.ip4.ip4.ip4]\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-XCLIENT ADDR NAME PORT LOGIN DESTADDR DESTPORT\r
+250 HELP\r
+220 XCLIENT success\r
+250-myhost.test.ex Hello proxylookedupname.net [127.0.0.2]\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-XCLIENT ADDR NAME PORT LOGIN DESTADDR DESTPORT\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmaY-0005vi-00\r
+
+**** SMTP testing: that is not a real message id!
+
+220 XCLIENT success\r
+250-myhost.test.ex Hello anotherhelo [127.0.0.3]\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-XCLIENT ADDR NAME PORT LOGIN DESTADDR DESTPORT\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmaZ-0005vi-00\r
+
+**** SMTP testing: that is not a real message id!
+
+250 OK\r
+503 mail transaction in progress\r
+250 Reset OK\r
+220 XCLIENT success\r
+503 HELO or EHLO required\r
+221 myhost.test.ex closing connection\r
+### (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\r
+250-myhost.test.ex Hello xclientproxy [ip4.ip4.ip4.ip4]\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-XCLIENT ADDR NAME PORT LOGIN DESTADDR DESTPORT\r
+250 HELP\r
+501 XCLIENT must have at least one operand\r
+501 XCLIENT: unrecognised parameter 'NONO'\r
+501 XCLIENT: unrecognised parameter 'NAMEfoobar'\r
+501-XCLIENT: unrecognised parameter 'SIXSIX'\r
+501 Too many syntax or protocol errors\r
+### (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\r
+250-myhost.test.ex Hello xclientproxy [ip4.ip4.ip4.ip4]\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250-XCLIENT ADDR NAME PORT LOGIN DESTADDR DESTPORT\r
+250 HELP\r
+501 XCLIENT: zero-length value for param\r
+501 XCLIENT: missing value for parameter 'NAME'\r
+421 myhost.test.ex lost input connection\r
+
+******** 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