[exim-cvs] OpenSSL: tls_eccurves list support. Bug 2955

Startseite
Nachricht löschen
Nachricht beantworten
Autor: Exim Git Commits Mailing List
Datum:  
To: exim-cvs
Betreff: [exim-cvs] OpenSSL: tls_eccurves list support. Bug 2955
Gitweb: https://git.exim.org/exim.git/commitdiff/42f1855e94bd87f98bc6c74255be53ed6d805ba6
Commit:     42f1855e94bd87f98bc6c74255be53ed6d805ba6
Parent:     31c546c4d0c3baf1b1e0ab292b4d096cffe64c34
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Sat Jan 7 00:17:08 2023 +0000
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Sat Jan 7 16:00:19 2023 +0000


    OpenSSL: tls_eccurves list support.  Bug 2955
---
 doc/doc-docbook/spec.xfpt      |  17 +++--
 doc/doc-txt/NewStuff           |   2 +
 src/src/tls-openssl.c          | 146 +++++++++++++++++++++++++----------------
 src/src/tls.c                  |   3 +-
 test/confs/2149                |  13 +---
 test/log/2149                  |  41 +++++++-----
 test/scripts/2100-OpenSSL/2149 |  25 ++++---
 7 files changed, 146 insertions(+), 101 deletions(-)


diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 9243bd3f9..7c8dee36f 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -18454,20 +18454,25 @@ prior to the 4.80 release, as Debian used to patch Exim to raise the minimum
acceptable bound from 1024 to 2048.


-.option tls_eccurve main string&!! &`auto`&
+.option tls_eccurve main string list&!! &`auto`&
.cindex TLS "EC cryptography"
-This option selects a EC curve for use by Exim when used with OpenSSL.
+This option selects EC curves for use by Exim when used with OpenSSL.
It has no effect when Exim is used with GnuTLS.

-After expansion it must contain a valid EC curve parameter, such as
-&`prime256v1`&, &`secp384r1`&, or &`P-512`&. Consult your OpenSSL manual
-for valid selections.
+After expansion it must contain
+.new
+one or (only for OpenSSL versiona 1.1.1 onwards) more
+.wen
+EC curve names, such as &`prime256v1`&, &`secp384r1`&, or &`P-521`&.
+Consult your OpenSSL manual for valid curve names.

For OpenSSL versions before (and not including) 1.0.2, the string
&`auto`& selects &`prime256v1`&. For more recent OpenSSL versions
&`auto`& tells the library to choose.

-If the option expands to an empty string, no EC curves will be enabled.
+.new
+If the option expands to an empty string, the effect is undefined.
+.wen


.option tls_ocsp_file main string&!! unset
diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
index b00399511..c1e139e35 100644
--- a/doc/doc-txt/NewStuff
+++ b/doc/doc-txt/NewStuff
@@ -19,6 +19,8 @@ Version 4.97

5. The smtp transport option "max_rcpt" is now expanded before use.

+ 6. The tls_eccurve option for OpenSSL now takes a list of group names
+
Version 4.96
------------

diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c
index 513ba0d3a..96be7c4a2 100644
--- a/src/src/tls-openssl.c
+++ b/src/src/tls-openssl.c
@@ -122,6 +122,7 @@ change this guard and punt the issue for a while longer. */
 #  define EXIM_HAVE_OPENSSL_CIPHER_STD_NAME
 #  define EXIM_HAVE_EXP_CHNL_BNGNG
 #  define EXIM_HAVE_OPENSSL_OCSP_RESP_GET0_SIGNER
+#  define EXIM_HAVE_OPENSSL_SET1_GROUPS
 # else
 #  define OPENSSL_BAD_SRVR_OURCERT
 # endif
@@ -700,6 +701,41 @@ return TRUE;
 *               Initialize for ECDH              *
 *************************************************/


+/* "auto" needs to be handled carefully.
+OpenSSL <  1.0.2: we do not select anything, but fallback to prime256v1
+OpenSSL <  1.1.0: we have to call SSL_CTX_set_ecdh_auto
+                  (openssl/ssl.h defines SSL_CTRL_SET_ECDH_AUTO)
+OpenSSL >= 1.1.0: we do not set anything, the libray does autoselection
+                  https://github.com/openssl/openssl/commit/fe6ef2472db933f01b59cad82aa925736935984b
+
+*/
+
+static uschar *
+init_ecdh_auto(SSL_CTX * ctx)
+{
+#if OPENSSL_VERSION_NUMBER < 0x10002000L
+DEBUG(D_tls) debug_printf(
+  " ECDH OpenSSL < 1.0.2: temp key parameter settings: overriding \"auto\" with \"prime256v1\"\n");
+return US"prime256v1";
+
+#else
+# if defined SSL_CTRL_SET_ECDH_AUTO
+
+DEBUG(D_tls) debug_printf(
+  " ECDH OpenSSL 1.0.2+: temp key parameter settings: autoselection\n");
+SSL_CTX_set_ecdh_auto(sctx, 1);
+return NULL;
+
+# else
+
+DEBUG(D_tls) debug_printf(
+  " ECDH OpenSSL 1.1.0+: temp key parameter settings: library default selection\n");
+return NULL;
+
+# endif
+#endif
+}
+
 /* Load parameters for ECDH encryption.  Server only.


For now, we stick to NIST P-256 because: it's simple and easy to configure;
@@ -730,72 +766,76 @@ init_ecdh(SSL_CTX * sctx, uschar ** errstr)
return TRUE;
#else

-uschar * exp_curve;
-int nid, rc;
-
# ifndef EXIM_HAVE_ECDH
DEBUG(D_tls)
debug_printf(" No OpenSSL API to define ECDH parameters, skipping\n");
return TRUE;
# else

+uschar * exp_curve;
+int ngroups, rc, sep;
+const uschar * curves_list, * curve;
+# ifdef EXIM_HAVE_OPENSSL_SET1_GROUPS
+int nids[16];
+# else
+int nids[1];
+# endif
+
if (!expand_check(tls_eccurve, US"tls_eccurve", &exp_curve, errstr))
return FALSE;

/* Is the option deliberately empty? */

if (!exp_curve || !*exp_curve)
- {
-#if OPENSSL_VERSION_NUMBER >= 0x10002000L
- DEBUG(D_tls) debug_printf( " ECDH OpenSSL 1.0.2+: clearing curves list\n");
- (void) SSL_CTX_set1_curves(sctx, &nid, 0);
-#endif
return TRUE;
- }

-/* "auto" needs to be handled carefully.
- * OpenSSL <  1.0.2: we do not select anything, but fallback to prime256v1
- * OpenSSL <  1.1.0: we have to call SSL_CTX_set_ecdh_auto
- *                   (openssl/ssl.h defines SSL_CTRL_SET_ECDH_AUTO)
- * OpenSSL >= 1.1.0: we do not set anything, the libray does autoselection
- *                   https://github.com/openssl/openssl/commit/fe6ef2472db933f01b59cad82aa925736935984b
- */
-if (Ustrcmp(exp_curve, "auto") == 0)
-  {
-#if OPENSSL_VERSION_NUMBER < 0x10002000L
-  DEBUG(D_tls) debug_printf(
-    " ECDH OpenSSL < 1.0.2: temp key parameter settings: overriding \"auto\" with \"prime256v1\"\n");
-  exp_curve = US"prime256v1";
-#else
-# if defined SSL_CTRL_SET_ECDH_AUTO
-  DEBUG(D_tls) debug_printf(
-    " ECDH OpenSSL 1.0.2+: temp key parameter settings: autoselection\n");
-  SSL_CTX_set_ecdh_auto(sctx, 1);
-  return TRUE;
-# else
-  DEBUG(D_tls) debug_printf(
-    " ECDH OpenSSL 1.1.0+: temp key parameter settings: library default selection\n");
-  return TRUE;
-# endif
-#endif
-  }
+/* Limit the list to hardwired array size. Drop out if any element is "suto". */


-if (  (nid = OBJ_sn2nid       (CCS exp_curve)) == NID_undef
-#   ifdef EXIM_HAVE_OPENSSL_EC_NIST2NID
-   && (nid = EC_curve_nist2nid(CCS exp_curve)) == NID_undef
-#   endif
-   )
-  {
-  uschar * s = string_sprintf("Unknown curve name tls_eccurve '%s'", exp_curve);
-  DEBUG(D_tls) debug_printf("TLS error '%s'\n", s);
-  if (errstr) *errstr = s;
-  return FALSE;
-  }
+curves_list = exp_curve;
+sep = 0;
+for (ngroups = 0;
+       ngroups < nelem(nids)
+    && (curve = string_nextinlist(&curves_list, &sep, NULL, 0));
+    )
+  if (Ustrcmp(curve, "auto") == 0)
+    {
+    DEBUG(D_tls) if (ngroups > 0)
+      debug_printf(" tls_eccurve 'auto' item takes precedence\n");
+    if ((exp_curve = init_ecdh_auto(sctx))) break; /* have a curve name to set */
+    return TRUE;                   /* all done */
+    }
+  else
+    ngroups++;


-# if OPENSSL_VERSION_NUMBER < 0x30000000L
+/* Translate to NIDs */
+
+curves_list = exp_curve;
+for (ngroups = 0; curve = string_nextinlist(&curves_list, &sep, NULL, 0);
+     ngroups++)
+  if (  (nids[ngroups] = OBJ_sn2nid       (CCS curve)) == NID_undef
+#  ifdef EXIM_HAVE_OPENSSL_EC_NIST2NID
+     && (nids[ngroups] = EC_curve_nist2nid(CCS curve)) == NID_undef
+#  endif
+     )
+    {
+    uschar * s = string_sprintf("Unknown curve name in tls_eccurve '%s'", curve);
+    DEBUG(D_tls) debug_printf("TLS error: %s\n", s);
+    if (errstr) *errstr = s;
+    return FALSE;
+    }
+
+#  ifdef EXIM_HAVE_OPENSSL_SET1_GROUPS
+/* Set the groups */
+
+if ((rc = SSL_CTX_set1_groups(sctx, nids, ngroups)) == 0)
+  tls_error(string_sprintf("Error enabling '%s' group(s)", exp_curve), NULL, NULL, errstr);
+else
+  DEBUG(D_tls) debug_printf(" ECDH: enabled '%s' group(s)\n", exp_curve);
+
+#  else        /* Cannot handle a list; only 1 element nids array */
  {
   EC_KEY * ecdh;
-  if (!(ecdh = EC_KEY_new_by_curve_name(nid)))
+  if (!(ecdh = EC_KEY_new_by_curve_name(nids[0])))
     {
     tls_error(US"Unable to create ec curve", NULL, NULL, errstr);
     return FALSE;
@@ -810,15 +850,7 @@ if (  (nid = OBJ_sn2nid       (CCS exp_curve)) == NID_undef
     DEBUG(D_tls) debug_printf(" ECDH: enabled '%s' curve\n", exp_curve);
   EC_KEY_free(ecdh);
  }
-
-#else    /* v 3.0.0 + */
-
-if ((rc = SSL_CTX_set1_groups(sctx, &nid, 1)) == 0)
-  tls_error(string_sprintf("Error enabling '%s' group", exp_curve), NULL, NULL, errstr);
-else
-  DEBUG(D_tls) debug_printf(" ECDH: enabled '%s' group\n", exp_curve);
-
-#endif
+#  endif    /*!EXIM_HAVE_OPENSSL_SET1_GROUPS*/


return !!rc;

diff --git a/src/src/tls.c b/src/src/tls.c
index 4a23aaae9..f7be5293d 100644
--- a/src/src/tls.c
+++ b/src/src/tls.c
@@ -106,7 +106,8 @@ Returns:    TRUE if OK; result may still be NULL after forced failure
 */


 static BOOL
-expand_check(const uschar *s, const uschar *name, uschar **result, uschar ** errstr)
+expand_check(const uschar * s, const uschar * name,
+  uschar ** result, uschar ** errstr)
 {
 if (!s)
   *result = NULL;
diff --git a/test/confs/2149 b/test/confs/2149
index 3369288bb..1782391de 100644
--- a/test/confs/2149
+++ b/test/confs/2149
@@ -30,22 +30,13 @@ client:
   errors_to =    ""


 server:
-  driver =    accept
-  retry_use_local_part
-  transport =    local_delivery
-
+  driver =    redirect
+  data =    :blackhole:


# ----- Transports -----

begin transports

-local_delivery:
-  driver =    appendfile
-  file =    DIR/test-mail/$local_part
-  create_file =    DIR/test-mail
-  headers_add =    TLS: cipher=$tls_cipher peerdn=$tls_peerdn
-  user =    CALLER
-
 send_to_server:
   driver =    smtp
   allow_localhost
diff --git a/test/log/2149 b/test/log/2149
index 3832ba076..91b48eee4 100644
--- a/test/log/2149
+++ b/test/log/2149
@@ -5,41 +5,48 @@
 1999-03-02 09:44:33 10HmaZ-0005vi-00 => explicitauto@??? R=client T=send_to_server H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes C="250 OK id=10HmbA-0005vi-00"
 1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
 1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbB-0005vi-00 => explicitempty@??? R=client T=send_to_server H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes C="250 OK id=10HmbC-0005vi-00"
+1999-03-02 09:44:33 10HmbB-0005vi-00 => prime256v1@??? R=client T=send_to_server H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes C="250 OK id=10HmbC-0005vi-00"
 1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
 1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbD-0005vi-00 => prime256v1@??? R=client T=send_to_server H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes C="250 OK id=10HmbE-0005vi-00"
+1999-03-02 09:44:33 10HmbD-0005vi-00 => secp384r1@??? R=client T=send_to_server H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes C="250 OK id=10HmbE-0005vi-00"
 1999-03-02 09:44:33 10HmbD-0005vi-00 Completed
 1999-03-02 09:44:33 10HmbF-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbF-0005vi-00 => secp384r1@??? R=client T=send_to_server H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes C="250 OK id=10HmbG-0005vi-00"
+1999-03-02 09:44:33 10HmbF-0005vi-00 H=127.0.0.1 [127.0.0.1]: a TLS session is required, but an attempt to start TLS failed
+1999-03-02 09:44:33 10HmbF-0005vi-00 == user_fail@??? R=client T=send_to_server defer (-38) H=127.0.0.1 [127.0.0.1]: a TLS session is required, but an attempt to start TLS failed
+1999-03-02 09:44:33 10HmbF-0005vi-00 ** user_fail@???: retry timeout exceeded
+1999-03-02 09:44:33 10HmbF-0005vi-00 user_fail@???: error ignored
 1999-03-02 09:44:33 10HmbF-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbH-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbH-0005vi-00 H=127.0.0.1 [127.0.0.1]: a TLS session is required, but an attempt to start TLS failed
-1999-03-02 09:44:33 10HmbH-0005vi-00 == user_fail@??? R=client T=send_to_server defer (-38) H=127.0.0.1 [127.0.0.1]: a TLS session is required, but an attempt to start TLS failed
-1999-03-02 09:44:33 10HmbH-0005vi-00 ** user_fail@???: retry timeout exceeded
-1999-03-02 09:44:33 10HmbH-0005vi-00 user_fail@???: error ignored
-1999-03-02 09:44:33 10HmbH-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbG-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmbG-0005vi-00 => user_list2@??? R=client T=send_to_server H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes C="250 OK id=10HmbH-0005vi-00"
+1999-03-02 09:44:33 10HmbG-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbI-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmbI-0005vi-00 => user_list_auto@??? R=client T=send_to_server H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes C="250 OK id=10HmbJ-0005vi-00"
+1999-03-02 09:44:33 10HmbI-0005vi-00 Completed


******** 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 10HmaY-0005vi-00 <= <> H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmaX-0005vi-00@???
-1999-03-02 09:44:33 10HmaY-0005vi-00 => optnotpresent <optnotpresent@???> R=server T=local_delivery
+1999-03-02 09:44:33 10HmaY-0005vi-00 => :blackhole: <optnotpresent@???> R=server
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
1999-03-02 09:44:33 exim x.yz daemon started: pid=p1235, no queue runs, listening for SMTP on port PORT_D
1999-03-02 09:44:33 10HmbA-0005vi-00 <= <> H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmaZ-0005vi-00@???
-1999-03-02 09:44:33 10HmbA-0005vi-00 => explicitauto <explicitauto@???> R=server T=local_delivery
+1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: <explicitauto@???> R=server
1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
1999-03-02 09:44:33 exim x.yz daemon started: pid=p1236, no queue runs, listening for SMTP on port PORT_D
1999-03-02 09:44:33 10HmbC-0005vi-00 <= <> H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmbB-0005vi-00@???
-1999-03-02 09:44:33 10HmbC-0005vi-00 => explicitempty <explicitempty@???> R=server T=local_delivery
+1999-03-02 09:44:33 10HmbC-0005vi-00 => :blackhole: <prime256v1@???> R=server
1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
1999-03-02 09:44:33 exim x.yz daemon started: pid=p1237, no queue runs, listening for SMTP on port PORT_D
1999-03-02 09:44:33 10HmbE-0005vi-00 <= <> H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmbD-0005vi-00@???
-1999-03-02 09:44:33 10HmbE-0005vi-00 => prime256v1 <prime256v1@???> R=server T=local_delivery
+1999-03-02 09:44:33 10HmbE-0005vi-00 => :blackhole: <secp384r1@???> R=server
1999-03-02 09:44:33 10HmbE-0005vi-00 Completed
1999-03-02 09:44:33 exim x.yz daemon started: pid=p1238, no queue runs, listening for SMTP on port PORT_D
-1999-03-02 09:44:33 10HmbG-0005vi-00 <= <> H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmbF-0005vi-00@???
-1999-03-02 09:44:33 10HmbG-0005vi-00 => secp384r1 <secp384r1@???> R=server T=local_delivery
-1999-03-02 09:44:33 10HmbG-0005vi-00 Completed
+1999-03-02 09:44:33 TLS error on connection from localhost (myhost.test.ex) [127.0.0.1] Unknown curve name in tls_eccurve 'bogus'
1999-03-02 09:44:33 exim x.yz daemon started: pid=p1239, no queue runs, listening for SMTP on port PORT_D
-1999-03-02 09:44:33 TLS error on connection from localhost (myhost.test.ex) [127.0.0.1] Unknown curve name tls_eccurve 'bogus'
+1999-03-02 09:44:33 10HmbH-0005vi-00 <= <> H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmbG-0005vi-00@???
+1999-03-02 09:44:33 10HmbH-0005vi-00 => :blackhole: <user_list2@???> R=server
+1999-03-02 09:44:33 10HmbH-0005vi-00 Completed
+1999-03-02 09:44:33 exim x.yz daemon started: pid=p1240, no queue runs, listening for SMTP on port PORT_D
+1999-03-02 09:44:33 10HmbJ-0005vi-00 <= <> H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmbI-0005vi-00@???
+1999-03-02 09:44:33 10HmbJ-0005vi-00 => :blackhole: <user_list_auto@???> R=server
+1999-03-02 09:44:33 10HmbJ-0005vi-00 Completed
diff --git a/test/scripts/2100-OpenSSL/2149 b/test/scripts/2100-OpenSSL/2149
index f1af49907..18b43bd5e 100644
--- a/test/scripts/2100-OpenSSL/2149
+++ b/test/scripts/2100-OpenSSL/2149
@@ -17,16 +17,8 @@ exim -odf explicitauto@???
****
killdaemon
#
-# Explicit tls_eccurve setting of ""
-# - unclear this works. At least with OpenSSL 3.0.5 we still get an x25519 keyshare in the Server Hello
-exim -DSERVER=server -DDATA= -bd -oX PORT_D
-****
-exim -odf explicitempty@???
-****
-killdaemon
-#
# prime256v1
-# Oddly, 3.0.5 packets show an EC-groups negotiation of C:x255519 S:secp256r1 C:secp384r1 S:secp384r1.
+# Oddly, 3.0.5 packets show an EC-groups negotiation of C:x255519 S:secp256r1 C:secp256r1 S:secp256r1.
# Hoever, note that RFC 8446 (TLS1.3) does NOT include prime256v1 as one of the allowable
# supported groups (and it's not in the client "supported groups" extension, so what we see seems good.
exim -DSERVER=server -DDATA=prime256v1 -bd -oX PORT_D
@@ -50,5 +42,20 @@ exim -odf user_fail@???
****
killdaemon
#
+# Two-element list - will fail for pre- 1.1.1 OpenSSL
+# - the Hello Retry Req goes out with the earliest one from the list which matches the client's Supported Groups
+exim -DSERVER=server -DDATA=P-521:secp384r1 -bd -oX PORT_D
+****
+exim -odf user_list2@???
+****
+killdaemon
+#
+#
+# List with an "auto" element embedded, which should override.
+exim -DSERVER=server '-DDATA= P-521 : P-384 : auto : P-256' -bd -oX PORT_D
+****
+exim -odf user_list_auto@???
+****
+killdaemon
#
no_message_check