EXTERNAL authenticator
authorJeremy Harris <jgh146exb@wizmail.org>
Sat, 5 Jan 2019 20:40:08 +0000 (20:40 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Sat, 5 Jan 2019 20:46:13 +0000 (20:46 +0000)
21 files changed:
doc/doc-docbook/spec.xfpt
doc/doc-txt/NewStuff
doc/doc-txt/OptionLists.txt
src/OS/Makefile-Base
src/scripts/MakeLinks
src/src/EDITME
src/src/auths/Makefile
src/src/auths/external.c [new file with mode: 0644]
src/src/auths/external.h [new file with mode: 0644]
src/src/config.h.defaults
src/src/drtables.c
test/confs/3720 [new file with mode: 0644]
test/confs/3721 [new symlink]
test/log/3720 [new file with mode: 0644]
test/log/3721 [new file with mode: 0644]
test/scripts/3720-external-auth-GnuTLS/3720 [new file with mode: 0644]
test/scripts/3720-external-auth-GnuTLS/REQUIRES [new file with mode: 0644]
test/scripts/3721-external-auth-OpenSSL/3721 [new file with mode: 0644]
test/scripts/3721-external-auth-OpenSSL/REQUIRES [new file with mode: 0644]
test/stdout/3720 [new file with mode: 0644]
test/stdout/3721 [new file with mode: 0644]

index c8f5a600b6f1aee05903626e123ad456cde00daf..f2902dc959863fbbbfc30fcf08af06204e5b1ba4 100644 (file)
@@ -26009,6 +26009,7 @@ included by setting
 AUTH_CRAM_MD5=yes
 AUTH_CYRUS_SASL=yes
 AUTH_DOVECOT=yes
+AUTH_EXTERNAL=yes
 AUTH_GSASL=yes
 AUTH_HEIMDAL_GSSAPI=yes
 AUTH_PLAINTEXT=yes
@@ -26020,15 +26021,20 @@ authentication mechanism (RFC 2195), and the second provides an interface to
 the Cyrus SASL authentication library.
 The third is an interface to Dovecot's authentication system, delegating the
 work via a socket interface.
-The fourth provides an interface to the GNU SASL authentication library, which
+.new
+The fourth provides for negotiation of authentication done via non-SMTP means,
+as defined by RFC 4422 Appendix A.
+.wen
+The fifth provides an interface to the GNU SASL authentication library, which
 provides mechanisms but typically not data sources.
-The fifth provides direct access to Heimdal GSSAPI, geared for Kerberos, but
+The sixth provides direct access to Heimdal GSSAPI, geared for Kerberos, but
 supporting setting a server keytab.
-The sixth can be configured to support
+The seventh can be configured to support
 the PLAIN authentication mechanism (RFC 2595) or the LOGIN mechanism, which is
-not formally documented, but used by several MUAs. The seventh authenticator
+not formally documented, but used by several MUAs.
+The eighth authenticator
 supports Microsoft's &'Secure Password Authentication'& mechanism.
-The eighth is an Exim authenticator but not an SMTP one;
+The last is an Exim authenticator but not an SMTP one;
 instead it can use information from a TLS negotiation.
 
 The authenticators are configured using the same syntax as other drivers (see
@@ -27260,6 +27266,143 @@ msn:
 
 
 
+. ////////////////////////////////////////////////////////////////////////////
+. ////////////////////////////////////////////////////////////////////////////
+
+.chapter "The external authenticator" "CHAPexternauth"
+.scindex IIDexternauth1 "&(external)& authenticator"
+.scindex IIDexternauth2 "authenticators" "&(external)&"
+.cindex "authentication" "Client Certificate"
+.cindex "authentication" "X509"
+.cindex "Certificate-based authentication"
+The &(external)& authenticator provides support for
+authentication based on non-SMTP information.
+The specification is in RFC 4422 Appendix A
+(&url(https://tools.ietf.org/html/rfc4422)).
+It is only a transport and negotiation mechanism;
+the process of authentication is entirely controlled
+by the server configuration.
+
+The client presents an identity in-clear.
+It is probably wise for a server to only advertise,
+and for clients to only attempt,
+this authentication method on a secure (eg. under TLS) connection.
+
+One possible use, compatible with the
+K-9 Mail Andoid client (&url(https://k9mail.github.io/)),
+is for using X509 client certificates.
+
+It thus overlaps in function with the TLS authenticator
+(see &<<CHAPtlsauth>>&)
+but is a full SMTP SASL authenticator
+rather than being implicit for TLS-connection carried
+client certificates only.
+
+The examples and discussion in this chapter assume that 
+client-certificate authentication is being done.
+
+The client must present a certificate,
+for which it must have been requested via the
+&%tls_verify_hosts%& or &%tls_try_verify_hosts%& main options
+(see &<<CHAPTLS>>&).
+For authentication to be effective the certificate should be
+verifiable against a trust-anchor certificate known to the server.
+
+.section "External options" "SECTexternsoptions"
+.cindex "options" "&(external)& authenticator (server)"
+The &(external)& authenticator has two server options:
+
+.option server_param2 external string&!! unset
+.option server_param3 external string&!! unset
+.cindex "variables (&$auth1$& &$auth2$& etc)" "in &(external)& authenticator"
+These options are expanded before the &%server_condition%& option
+and the result are placed in &$auth2$& and &$auth3$& resectively.
+If the expansion is forced to fail, authentication fails. Any other expansion
+failure causes a temporary error code to be returned.
+
+They can be used to clarify the coding of a complex &%server_condition%&.
+
+.section "Using external in a server" "SECTexternserver"
+.cindex "AUTH" "in &(external)& authenticator"
+.cindex "numerical variables (&$1$& &$2$& etc)" &&&
+        "in &(external)& authenticator"
+.vindex "&$auth1$&, &$auth2$&, etc"
+.cindex "base64 encoding" "in &(external)& authenticator"
+
+When running as a server, &(external)& performs the authentication test by
+expanding a string. The data sent by the client with the AUTH command, or in
+response to subsequent prompts, is base64 encoded, and so may contain any byte
+values when decoded. The decoded value is treated as
+an identity for authentication and
+placed in the expansion variable &$auth1$&.
+
+For compatibility with previous releases of Exim, the value is also placed in
+the expansion variable &$1$&. However, the use of this
+variable for this purpose is now deprecated, as it can lead to confusion in
+string expansions that also use them for other things.
+
+.vindex "&$authenticated_id$&"
+Once an identity has been received,
+&%server_condition%& is expanded. If the expansion is forced to fail,
+authentication fails. Any other expansion failure causes a temporary error code
+to be returned. If the result of a successful expansion is an empty string,
+&"0"&, &"no"&, or &"false"&, authentication fails. If the result of the
+expansion is &"1"&, &"yes"&, or &"true"&, authentication succeeds and the
+generic &%server_set_id%& option is expanded and saved in &$authenticated_id$&.
+For any other result, a temporary error code is returned, with the expanded
+string as the error text.
+
+Example:
+.code
+ext_ccert_san_mail:
+  driver =            external
+  public_name =       EXTERNAL
+
+  server_advertise_condition = $tls_in_certificate_verified
+  server_param2 =     ${certextract {subj_altname,mail,>:} \
+                                    {$tls_in_peercert}}
+  server_condition =  ${if forany {$auth2} \
+                            {eq {$item}{$auth1}}}
+  server_set_id =     $auth1
+.endd
+This accepts a client certificate that is verifiable against any
+of your configured trust-anchors
+(which usually means the full set of public CAs)
+and which has a mail-SAN matching the claimed identity sent by the client.
+
+Note that, up to TLS1.2, the client cert is on the wire in-clear, including the SAN,
+The account name is therefore guessable by an opponent.
+TLS 1.3 protects both server and client certificates, and is not vulnerable
+in this way.
+Likewise, a traditional plaintext SMTP AUTH done inside TLS is not.
+
+
+.section "Using external in a client" "SECTexternclient"
+.cindex "options" "&(external)& authenticator (client)"
+The &(external)& authenticator has one client option:
+
+.option client_send external string&!! unset
+This option is expanded and sent with the AUTH command as the
+identity being asserted.
+
+Example:
+.code
+ext_ccert:
+  driver =      external
+  public_name = EXTERNAL
+
+  client_condition = ${if !eq{$tls_out_cipher}{}}
+  client_send = myaccount@smarthost.example.net
+.endd
+
+
+.ecindex IIDexternauth1
+.ecindex IIDexternauth2
+
+
+
+
+
 . ////////////////////////////////////////////////////////////////////////////
 . ////////////////////////////////////////////////////////////////////////////
 
index fb336b8af2413fa056d587d7e644986dc27cc507..b2a61d43cea161d4f4e9346eeca366d4911acefc 100644 (file)
@@ -6,6 +6,11 @@ Before a formal release, there may be quite a lot of detail so that people can
 test from the snapshots or the Git before the documentation is updated. Once
 the documentation is updated, this file is reduced to a short list.
 
+Version 4.92
+--------------
+
+ 1. An "external" authenticator, per RFC 4422 Appendix A.
+
 Version 4.92
 --------------
 
index fec47946a384d288fc0d60f347186e183d9c9848..5586e7d347a699ddbfa096aafe558850e49fafc7 100644 (file)
@@ -132,6 +132,7 @@ client_ignore_invalid_base64         boolean         false         plaintext
 client_name                          string*         +             cram_md5          3.10
 client_secret                        string*         unset         cram_md5          3.10
 client_send                          string*         unset         plaintext         3.10
+client_send                          string*         unset         external (auth)   4.93
 command                              string*         unset         lmtp              3.20
                                                      unset         pipe
                                                      unset         queryprogram      4.00
@@ -498,6 +499,9 @@ server_keytab                        string*         unset         heimdal_gssap
 server_mail_auth_condition           string*         unset         authenticators    3.22
 server_mech                          string          public_name   cyrus_sasl,gsasl  4.43 (cyrus-only) 4.80 (others)
 server_password                      string          unset         gsasl             4.80
+server_param1                       string*         unset         tls (auth)        4.86
+server_param2                       string*         unset         tls (auth)        4.86 (tls-only) 4.93 (external)
+server_param3                       string*         unset         tls (auth)        4.86 (tls-only) 4.93 (external)
 server_prompts                       string*         unset         plaintext         3.10
 server_realm                         string          unset         cyrus_sasl,gsasl  4.43 (cyrus-only) 4.80 (others)
 server_scram_iter                    string*         unset         gsasl             4.80
index fed3134cffde98812477f093147abacfa2e6cdd9..79bec063b6157e9009b0e39824bb48fbaee2bb4c 100644 (file)
@@ -135,7 +135,7 @@ OBJ_MACRO = macro_predef.o \
        macro-smtp.o macro-accept.o macro-dnslookup.o macro-ipliteral.o macro-iplookup.o \
        macro-manualroute.o macro-queryprogram.o macro-redirect.o \
        macro-auth-spa.o macro-cram_md5.o macro-cyrus_sasl.o macro-dovecot.o macro-gsasl_exim.o \
-       macro-heimdal_gssapi.o macro-plaintext.o macro-spa.o macro-authtls.o \
+       macro-heimdal_gssapi.o macro-plaintext.o macro-spa.o macro-authtls.o macro-external.o \
        macro-dkim.o macro-malware.o macro-signing.o
 
 $(OBJ_MACRO):  $(MACRO_HSRC)
@@ -212,6 +212,9 @@ macro-cyrus_sasl.o :        auths/cyrus_sasl.c
 macro-dovecot.o:       auths/dovecot.c
        @echo "$(CC) -DMACRO_PREDEF auths/dovecot.c"
        $(FE)$(CC) -c $(CFLAGS) -DMACRO_PREDEF $(INCLUDE) -o $@ auths/dovecot.c
+macro-external.o:      auths/external.c
+       @echo "$(CC) -DMACRO_PREDEF auths/external.c"
+       $(FE)$(CC) -c $(CFLAGS) -DMACRO_PREDEF $(INCLUDE) -o $@ auths/external.c
 macro-gsasl_exim.o :   auths/gsasl_exim.c
        @echo "$(CC) -DMACRO_PREDEF auths/gsasl_exim.c"
        $(FE)$(CC) -c $(CFLAGS) -DMACRO_PREDEF $(INCLUDE) -o $@ auths/gsasl_exim.c
index 08f4ff1f8d01a56f27d41694b61d772f663aee27..f69bde437d59645d570e8d5f42cfc16a83c8844b 100755 (executable)
@@ -75,7 +75,7 @@ for f in README Makefile call_pam.c call_pwcheck.c \
   gsasl_exim.h get_data.c get_no64_data.c heimdal_gssapi.c heimdal_gssapi.h \
   md5.c xtextencode.c xtextdecode.c cram_md5.c cram_md5.h plaintext.c plaintext.h \
   pwcheck.c pwcheck.h auth-spa.c auth-spa.h dovecot.c dovecot.h sha1.c spa.c \
-  spa.h tls.c tls.h
+  spa.h tls.c tls.h external.c external.h
 do
   ln -s ../../src/auths/$f $f
 done
index cbb080545f125d96c162ce626ad9f8999ae408df..15360db9acd39eed61910e84ba54c3164ce78459 100644 (file)
@@ -643,6 +643,7 @@ FIXED_NEVER_USERS=root
 # AUTH_CRAM_MD5=yes
 # AUTH_CYRUS_SASL=yes
 # AUTH_DOVECOT=yes
+# AUTH_EXTERNAL=yes
 # AUTH_GSASL=yes
 # AUTH_GSASL_PC=libgsasl
 # AUTH_HEIMDAL_GSSAPI=yes
index 62ce9d0a965846ae2756fe1d804d2af0d984b2c8..402f1417a8d2d31920bf566025ffbf3cca001de8 100644 (file)
@@ -7,7 +7,7 @@
 
 OBJ = auth-spa.o call_pam.o call_pwcheck.o \
       call_radius.o check_serv_cond.o cram_md5.o cyrus_sasl.o dovecot.o \
-      get_data.o get_no64_data.o gsasl_exim.o heimdal_gssapi.o \
+      external.o get_data.o get_no64_data.o gsasl_exim.o heimdal_gssapi.o \
       md5.o plaintext.o pwcheck.o \
       spa.o tls.o xtextdecode.o xtextencode.o
 
@@ -36,6 +36,7 @@ xtextencode.o:      $(HDRS) xtextencode.c
 cram_md5.o:         $(HDRS) cram_md5.c cram_md5.h
 cyrus_sasl.o:       $(HDRS) cyrus_sasl.c cyrus_sasl.h
 dovecot.o:          $(HDRS) dovecot.c dovecot.h
+external.o:         $(HDRS) external.c external.h
 gsasl_exim.o:       $(HDRS) gsasl_exim.c gsasl_exim.h
 heimdal_gssapi.o:   $(HDRS) heimdal_gssapi.c heimdal_gssapi.h
 plaintext.o:        $(HDRS) plaintext.c plaintext.h
diff --git a/src/src/auths/external.c b/src/src/auths/external.c
new file mode 100644 (file)
index 0000000..10e1366
--- /dev/null
@@ -0,0 +1,158 @@
+/*************************************************
+*     Exim - an Internet mail transport agent    *
+*************************************************/
+
+/* Copyright (c) Jeremy Harris 2019 */
+/* See the file NOTICE for conditions of use and distribution. */
+
+/* This file provides an Exim authenticator driver for
+a server to verify a client SSL certificate, using the EXTERNAL
+method defined in RFC 4422 Appendix A.
+*/
+
+
+#include "../exim.h"
+#include "external.h"
+
+/* Options specific to the external authentication mechanism. */
+
+optionlist auth_external_options[] = {
+  { "client_send",     opt_stringptr,
+      (void *)(offsetof(auth_external_options_block, client_send)) },
+  { "server_param2",   opt_stringptr,
+      (void *)(offsetof(auth_external_options_block, server_param2)) },
+  { "server_param3",       opt_stringptr,
+      (void *)(offsetof(auth_external_options_block, server_param3)) },
+};
+
+/* Size of the options list. An extern variable has to be used so that its
+address can appear in the tables drtables.c. */
+
+int auth_external_options_count = nelem(auth_external_options);
+
+/* Default private options block for the authentication method. */
+
+auth_external_options_block auth_external_option_defaults = {
+    .server_param2 = NULL,
+    .server_param3 = NULL,
+
+    .client_send = NULL,
+};
+
+
+#ifdef MACRO_PREDEF
+
+/* Dummy values */
+void auth_external_init(auth_instance *ablock) {}
+int auth_external_server(auth_instance *ablock, uschar *data) {return 0;}
+int auth_external_client(auth_instance *ablock, void * sx,
+  int timeout, uschar *buffer, int buffsize) {return 0;}
+
+#else   /*!MACRO_PREDEF*/
+
+
+
+
+/*************************************************
+*          Initialization entry point            *
+*************************************************/
+
+/* Called for each instance, after its options have been read, to
+enable consistency checks to be done, or anything else that needs
+to be set up. */
+
+void
+auth_external_init(auth_instance *ablock)
+{
+auth_external_options_block * ob = (auth_external_options_block *)ablock->options_block;
+if (!ablock->public_name) ablock->public_name = ablock->name;
+if (ablock->server_condition) ablock->server = TRUE;
+if (ob->client_send) ablock->client = TRUE;
+}
+
+
+
+/*************************************************
+*             Server entry point                 *
+*************************************************/
+
+/* For interface, see auths/README */
+
+int
+auth_external_server(auth_instance * ablock, uschar * data)
+{
+auth_external_options_block * ob = (auth_external_options_block *)ablock->options_block;
+int rc;
+
+/* If data was supplied on the AUTH command, decode it, and split it up into
+multiple items at binary zeros. The strings are put into $auth1, $auth2, etc,
+up to a maximum. To retain backwards compatibility, they are also put int $1,
+$2, etc. If the data consists of the string "=" it indicates a single, empty
+string. */
+
+if (*data)
+  if ((rc = auth_read_input(data)) != OK)
+    return rc;
+
+/* Now go through the list of prompt strings. Skip over any whose data has
+already been provided as part of the AUTH command. For the rest, send them
+out as prompts, and get a data item back. If the data item is "*", abandon the
+authentication attempt. Otherwise, split it into items as above. */
+
+if (expand_nmax == 0)  /* skip if rxd data */
+  if ((rc = auth_prompt(CUS"")) != OK)
+    return rc;
+
+if (ob->server_param2)
+  {
+  uschar * s = expand_string(ob->server_param2);
+  auth_vars[expand_nmax] = s;
+  expand_nstring[++expand_nmax] = s;
+  expand_nlength[expand_nmax] = Ustrlen(s);
+  if (ob->server_param3)
+    {
+    s = expand_string(ob->server_param3);
+    auth_vars[expand_nmax] = s;
+    expand_nstring[++expand_nmax] = s;
+    expand_nlength[expand_nmax] = Ustrlen(s);
+    }
+  }
+
+return auth_check_serv_cond(ablock);
+}
+
+
+
+/*************************************************
+*              Client entry point                *
+*************************************************/
+
+/* For interface, see auths/README */
+
+int
+auth_external_client(
+  auth_instance *ablock,                 /* authenticator block */
+  void * sx,                            /* smtp connextion */
+  int timeout,                           /* command timeout */
+  uschar *buffer,                        /* buffer for reading response */
+  int buffsize)                          /* size of buffer */
+{
+auth_external_options_block *ob =
+  (auth_external_options_block *)(ablock->options_block);
+const uschar * text = ob->client_send;
+int rc;
+
+/* We output an AUTH command with one expanded argument, the client_send option */
+
+if ((rc = auth_client_item(sx, ablock, &text, AUTH_ITEM_FIRST | AUTH_ITEM_LAST,
+      timeout, buffer, buffsize)) != OK)
+  return rc == DEFER ? FAIL : rc;
+
+if (text) auth_vars[0] = string_copy(text);
+return OK;
+}
+
+
+
+#endif   /*!MACRO_PREDEF*/
+/* End of external.c */
diff --git a/src/src/auths/external.h b/src/src/auths/external.h
new file mode 100644 (file)
index 0000000..7d43650
--- /dev/null
@@ -0,0 +1,32 @@
+/*************************************************
+*     Exim - an Internet mail transport agent    *
+*************************************************/
+
+/* Copyright (c) Jeremy Harris 2019 */
+/* See the file NOTICE for conditions of use and distribution. */
+
+/* Private structure for the private options. */
+
+typedef struct {
+  uschar * server_param2;
+  uschar * server_param3;
+
+  uschar * client_send;
+} auth_external_options_block;
+
+/* Data for reading the private options. */
+
+extern optionlist auth_external_options[];
+extern int auth_external_options_count;
+
+/* Block containing default values. */
+
+extern auth_external_options_block auth_external_option_defaults;
+
+/* The entry points for the mechanism */
+
+extern void auth_external_init(auth_instance *);
+extern int auth_external_server(auth_instance *, uschar *);
+extern int auth_external_client(auth_instance *, void *, int, uschar *, int);
+
+/* End of external.h */
index 7c2e534f3cc78322966a6825e190e1987e8ff4dd..74ec3f4df68ecfb46af269d357f240793dab8960 100644 (file)
@@ -24,6 +24,7 @@ Do not put spaces between # and the 'define'.
 #define AUTH_CRAM_MD5
 #define AUTH_CYRUS_SASL
 #define AUTH_DOVECOT
+#define AUTH_EXTERNAL
 #define AUTH_GSASL
 #define AUTH_HEIMDAL_GSSAPI
 #define AUTH_PLAINTEXT
index cd12dd1da8dc8350463e7a0741966b678b9ec1ec..54d03edab455878717585275f49e5cf267924883 100644 (file)
@@ -35,6 +35,10 @@ set to NULL for those that are not compiled into the binary. */
 #include "auths/dovecot.h"
 #endif
 
+#ifdef AUTH_EXTERNAL
+#include "auths/external.h"
+#endif
+
 #ifdef AUTH_GSASL
 #include "auths/gsasl_exim.h"
 #endif
@@ -101,6 +105,20 @@ auth_info auths_available[] = {
   },
 #endif
 
+#ifdef AUTH_EXTERNAL
+  {
+  .driver_name =       US"external",
+  .options =           auth_external_options,
+  .options_count =     &auth_external_options_count,
+  .options_block =     &auth_external_option_defaults,
+  .options_len =       sizeof(auth_external_options_block),
+  .init =              auth_external_init,
+  .servercode =                auth_external_server,
+  .clientcode =                auth_external_client,
+  .version_report =    NULL
+  },
+#endif
+
 #ifdef AUTH_GSASL
   {
   .driver_name =       US"gsasl",
diff --git a/test/confs/3720 b/test/confs/3720
new file mode 100644 (file)
index 0000000..6d8c467
--- /dev/null
@@ -0,0 +1,93 @@
+# Exim test configuration 3720
+
+SERVER=
+
+.include DIR/aux-var/tls_conf_prefix
+
+primary_hostname = myhost.test.ex
+log_selector = +received_recipients +outgoing_port
+
+# ----- Main settings -----
+
+acl_smtp_auth = log_call
+acl_smtp_mail = check_authd
+acl_smtp_rcpt = check_authd
+acl_smtp_data = ar_header
+
+queue_only
+queue_run_in_order
+trusted_users = CALLER
+
+tls_advertise_hosts = *
+tls_certificate = DIR/aux-fixed/cert1
+
+tls_verify_hosts = *
+tls_verify_certificates = DIR/aux-fixed/cert2
+
+
+# ----- ACL -----
+
+begin acl
+
+log_call:
+  accept   logwrite = Auth ACL called, after smtp cmd "$smtp_command"
+
+check_authd:
+  deny     message = authentication required
+          !authenticated = *
+  accept
+
+ar_header:
+  accept  add_header = :at_start:${authresults {$primary_hostname}}
+
+# ----- Authentication -----
+
+begin authenticators
+
+ext_ccert_cn:
+  driver =             external
+  public_name =                EXTERNAL
+
+  server_advertise_condition = ${if eq{$tls_in_cipher}{}{no}{yes}}
+  server_param2 =      ${certextract {subject,CN} {$tls_in_peercert}}
+  server_condition =   ${if eq {$auth2}{$auth1}}
+  server_set_id =      $auth1
+  server_debug_print = +++TLS \$auth1="$auth1"
+
+  client_send =                "Phil Pennock"
+
+
+# ----- Routers -----
+
+begin routers
+
+server_r:
+  driver =     accept
+  condition =  ${if eq {server}{SERVER}}
+  transport =  file
+
+client_r1:
+  driver =     accept
+  transport =  t1
+
+
+# ----- Transports -----
+
+begin transports
+
+t1:
+  driver = smtp
+  hosts = 127.0.0.1
+  port = PORT_D
+  allow_localhost
+  tls_certificate =            DIR/aux-fixed/cert2
+  tls_verify_certificates =    DIR/aux-fixed/cert1
+  tls_verify_cert_hostnames =  :
+  hosts_try_auth =             *
+
+file:
+  driver = appendfile
+  file = DIR/test-mail/$local_part
+  user = CALLER
+
+# End
diff --git a/test/confs/3721 b/test/confs/3721
new file mode 120000 (symlink)
index 0000000..e401101
--- /dev/null
@@ -0,0 +1 @@
+3720
\ No newline at end of file
diff --git a/test/log/3720 b/test/log/3720
new file mode 100644 (file)
index 0000000..f79e756
--- /dev/null
@@ -0,0 +1,11 @@
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= ok@test.ex U=CALLER P=local S=sss for x@y
+1999-03-02 09:44:33 Start queue run: pid=pppp
+1999-03-02 09:44:33 10HmaX-0005vi-00 => x@y R=client_r1 T=t1 H=127.0.0.1 [127.0.0.1]:1225 X=TLS_proto_and_cipher CV=yes A=ext_ccert_cn C="250 OK id=10HmaY-0005vi-00"
+1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp
+
+******** SERVER ********
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 Auth ACL called, after smtp cmd "AUTH EXTERNAL UGhpbCBQZW5ub2Nr"
+1999-03-02 09:44:33 Auth ACL called, after smtp cmd "AUTH EXTERNAL UGhpbCBQZW5ub2Nr"
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= ok@test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtpsa X=TLS_proto_and_cipher CV=yes A=ext_ccert_cn:Phil Pennock S=sss id=E10HmaX-0005vi-00@myhost.test.ex for x@y
diff --git a/test/log/3721 b/test/log/3721
new file mode 100644 (file)
index 0000000..f79e756
--- /dev/null
@@ -0,0 +1,11 @@
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= ok@test.ex U=CALLER P=local S=sss for x@y
+1999-03-02 09:44:33 Start queue run: pid=pppp
+1999-03-02 09:44:33 10HmaX-0005vi-00 => x@y R=client_r1 T=t1 H=127.0.0.1 [127.0.0.1]:1225 X=TLS_proto_and_cipher CV=yes A=ext_ccert_cn C="250 OK id=10HmaY-0005vi-00"
+1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp
+
+******** SERVER ********
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 Auth ACL called, after smtp cmd "AUTH EXTERNAL UGhpbCBQZW5ub2Nr"
+1999-03-02 09:44:33 Auth ACL called, after smtp cmd "AUTH EXTERNAL UGhpbCBQZW5ub2Nr"
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= ok@test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtpsa X=TLS_proto_and_cipher CV=yes A=ext_ccert_cn:Phil Pennock S=sss id=E10HmaX-0005vi-00@myhost.test.ex for x@y
diff --git a/test/scripts/3720-external-auth-GnuTLS/3720 b/test/scripts/3720-external-auth-GnuTLS/3720
new file mode 100644 (file)
index 0000000..49d9520
--- /dev/null
@@ -0,0 +1,38 @@
+# External authentication (server & client)
+munge tls_anycipher
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+#
+client-gnutls 127.0.0.1 PORT_D 127.0.0.1 DIR/aux-fixed/cert2 DIR/aux-fixed/cert2
+??? 220
+EHLO tester
+??? 250-
+??? 250-
+??? 250-
+??? 250-
+??? 250-STARTTLS
+??? 250 HELP
+STARTTLS
+??? 220
+EHLO tester
+??? 250-
+??? 250-
+??? 250-
+??? 250-
+??? 250-AUTH EXTERNAL
+??? 250 HELP
+AUTH EXTERNAL UGhpbCBQZW5ub2Nr
+??? 235
+quit
+??? 221
+****
+#
+exim -f ok@test.ex x@y
+****
+exim -q
+****
+#
+killdaemon
+no_msglog_check
diff --git a/test/scripts/3720-external-auth-GnuTLS/REQUIRES b/test/scripts/3720-external-auth-GnuTLS/REQUIRES
new file mode 100644 (file)
index 0000000..9e358e2
--- /dev/null
@@ -0,0 +1,2 @@
+authenticator external
+support GnuTLS
diff --git a/test/scripts/3721-external-auth-OpenSSL/3721 b/test/scripts/3721-external-auth-OpenSSL/3721
new file mode 100644 (file)
index 0000000..310b8d2
--- /dev/null
@@ -0,0 +1,38 @@
+# External authentication (server & client)
+munge tls_anycipher
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+#
+client-ssl 127.0.0.1 PORT_D 127.0.0.1 DIR/aux-fixed/cert2 DIR/aux-fixed/cert2
+??? 220
+EHLO tester
+??? 250-
+??? 250-
+??? 250-
+??? 250-
+??? 250-STARTTLS
+??? 250 HELP
+STARTTLS
+??? 220
+EHLO tester
+??? 250-
+??? 250-
+??? 250-
+??? 250-
+??? 250-AUTH EXTERNAL
+??? 250 HELP
+AUTH EXTERNAL UGhpbCBQZW5ub2Nr
+??? 235
+quit
+??? 221
+****
+#
+exim -f ok@test.ex x@y
+****
+exim -q
+****
+#
+killdaemon
+no_msglog_check
diff --git a/test/scripts/3721-external-auth-OpenSSL/REQUIRES b/test/scripts/3721-external-auth-OpenSSL/REQUIRES
new file mode 100644 (file)
index 0000000..c0a56a2
--- /dev/null
@@ -0,0 +1,2 @@
+authenticator external
+support OpenSSL
diff --git a/test/stdout/3720 b/test/stdout/3720
new file mode 100644 (file)
index 0000000..049c87d
--- /dev/null
@@ -0,0 +1,43 @@
+Connecting to 127.0.0.1 port 1225 ... connected
+Certificate file = TESTSUITE/aux-fixed/cert2
+Key file = TESTSUITE/aux-fixed/cert2
+??? 220
+<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+>>> EHLO tester
+??? 250-
+<<< 250-myhost.test.ex Hello tester [127.0.0.1]
+??? 250-
+<<< 250-SIZE 52428800
+??? 250-
+<<< 250-8BITMIME
+??? 250-
+<<< 250-PIPELINING
+??? 250-STARTTLS
+<<< 250-STARTTLS
+??? 250 HELP
+<<< 250 HELP
+>>> STARTTLS
+??? 220
+<<< 220 TLS go ahead
+Attempting to start TLS
+Succeeded in starting TLS
+>>> EHLO tester
+??? 250-
+<<< 250-myhost.test.ex Hello tester [127.0.0.1]
+??? 250-
+<<< 250-SIZE 52428800
+??? 250-
+<<< 250-8BITMIME
+??? 250-
+<<< 250-PIPELINING
+??? 250-AUTH EXTERNAL
+<<< 250-AUTH EXTERNAL
+??? 250 HELP
+<<< 250 HELP
+>>> AUTH EXTERNAL UGhpbCBQZW5ub2Nr
+??? 235
+<<< 235 Authentication succeeded
+>>> quit
+??? 221
+<<< 221 myhost.test.ex closing connection
+End of script
diff --git a/test/stdout/3721 b/test/stdout/3721
new file mode 100644 (file)
index 0000000..81878f9
--- /dev/null
@@ -0,0 +1,44 @@
+Connecting to 127.0.0.1 port 1225 ... connected
+Certificate file = TESTSUITE/aux-fixed/cert2
+Key file = TESTSUITE/aux-fixed/cert2
+??? 220
+<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+>>> EHLO tester
+??? 250-
+<<< 250-myhost.test.ex Hello tester [127.0.0.1]
+??? 250-
+<<< 250-SIZE 52428800
+??? 250-
+<<< 250-8BITMIME
+??? 250-
+<<< 250-PIPELINING
+??? 250-STARTTLS
+<<< 250-STARTTLS
+??? 250 HELP
+<<< 250 HELP
+>>> STARTTLS
+??? 220
+<<< 220 TLS go ahead
+Attempting to start TLS
+SSL connection using ke-RSA-AES256-SHA
+Succeeded in starting TLS
+>>> EHLO tester
+??? 250-
+<<< 250-myhost.test.ex Hello tester [127.0.0.1]
+??? 250-
+<<< 250-SIZE 52428800
+??? 250-
+<<< 250-8BITMIME
+??? 250-
+<<< 250-PIPELINING
+??? 250-AUTH EXTERNAL
+<<< 250-AUTH EXTERNAL
+??? 250 HELP
+<<< 250 HELP
+>>> AUTH EXTERNAL UGhpbCBQZW5ub2Nr
+??? 235
+<<< 235 Authentication succeeded
+>>> quit
+??? 221
+<<< 221 myhost.test.ex closing connection
+End of script