]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.12-20260410 master
authorWietse Z Venema <wietse@porcupine.org>
Fri, 10 Apr 2026 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <ietf-dane@dukhovni.org>
Sun, 12 Apr 2026 15:42:21 +0000 (01:42 +1000)
51 files changed:
postfix/.indent.pro
postfix/HISTORY
postfix/README_FILES/TLS_README
postfix/html/TLS_README.html
postfix/html/smtpd.8.html
postfix/man/man8/smtpd.8
postfix/mantools/postlink
postfix/proto/TLS_README.html
postfix/proto/stop.double-history
postfix/proto/stop.spell-cc
postfix/src/global/mail_version.h
postfix/src/postscreen/Makefile.in
postfix/src/smtp/Makefile.in
postfix/src/smtpd/Makefile.in
postfix/src/smtpd/smtpd.c
postfix/src/testing/make_attr.c
postfix/src/testing/make_attr.h
postfix/src/testing/match_attr_test.c
postfix/src/testing/mock_server_test.c
postfix/src/tls/Makefile.in
postfix/src/tls/tls_proxy.h
postfix/src/tls/tls_proxy_attr.h [new file with mode: 0644]
postfix/src/tls/tls_proxy_client_init_proto.c [new file with mode: 0644]
postfix/src/tls/tls_proxy_client_init_proto.h [new file with mode: 0644]
postfix/src/tls/tls_proxy_client_init_proto_test.c [new file with mode: 0644]
postfix/src/tls/tls_proxy_client_misc.c [deleted file]
postfix/src/tls/tls_proxy_client_param_proto.c [new file with mode: 0644]
postfix/src/tls/tls_proxy_client_param_proto.h [new file with mode: 0644]
postfix/src/tls/tls_proxy_client_param_proto_test.c [new file with mode: 0644]
postfix/src/tls/tls_proxy_client_print.c [deleted file]
postfix/src/tls/tls_proxy_client_start_proto.c [moved from postfix/src/tls/tls_proxy_client_scan.c with 54% similarity]
postfix/src/tls/tls_proxy_client_start_proto.h [new file with mode: 0644]
postfix/src/tls/tls_proxy_server_init_proto.c [moved from postfix/src/tls/tls_proxy_server_scan.c with 52% similarity]
postfix/src/tls/tls_proxy_server_init_proto.h [new file with mode: 0644]
postfix/src/tls/tls_proxy_server_init_proto_test.c [new file with mode: 0644]
postfix/src/tls/tls_proxy_server_param_proto.c [new file with mode: 0644]
postfix/src/tls/tls_proxy_server_param_proto.h [new file with mode: 0644]
postfix/src/tls/tls_proxy_server_param_proto_test.c [new file with mode: 0644]
postfix/src/tls/tls_proxy_server_print.c [deleted file]
postfix/src/tls/tls_proxy_server_start_proto.c [new file with mode: 0644]
postfix/src/tls/tls_proxy_server_start_proto.h [new file with mode: 0644]
postfix/src/util/attr.h
postfix/src/util/attr_print0.c
postfix/src/util/attr_print64.c
postfix/src/util/attr_print_plain.c
postfix/src/util/attr_scan0.c
postfix/src/util/attr_scan0.ref
postfix/src/util/attr_scan64.c
postfix/src/util/attr_scan64.ref
postfix/src/util/attr_scan_plain.c
postfix/src/util/attr_scan_plain.ref

index 8b17072544e8c65ad99b2b05d1c7291667a566d3..ff511fea19b43defa1a5ad0e8056277c454b0dc6 100644 (file)
 -TTLS_SCACHE
 -TTLS_SCACHE_ENTRY
 -TTLS_SERVER_INIT_PROPS
+-TTLS_SERVER_PARAMS
 -TTLS_SERVER_START_PROPS
 -TTLS_SESS_STATE
 -TTLS_TICKET_KEY
index d99f00d0e89282574e7390df52991ccab22a800f..23fac43c2b0b7217269448dafb1ff33e92c67948 100644 (file)
@@ -30826,6 +30826,51 @@ Apologies for any names omitted.
        Testing: expect_ptest_error() should be expect_ptest_log_event().
        File: global/hfrom_format_test.c.
 
+20260406
+
+       Documentation: some construction debris. Viktor Dukhovni.
+       File: proto/TLS_README.html.
+
+20260407
+
+       Tech debt: added 'bool' support to internal protocols.
+       util/attr.h, util/attr_print0.c, util/attr_print64.c,
+       util/attr_print_plain.c, util/attr_scan0.c, util/attr_scan0.ref,
+       util/attr_scan64.c, util/attr_scan64.ref, util/attr_scan_plain.c,
+       util/attr_scan_plain.ref. There is no code that uses this now,
+       but there are tests to make sure that it is works when neded.
+
+20260408
+
+       Testing: pass an output function argument to make_attr().
+       Files: testing/make_attr.[hc], testing/match_attr_test.c,
+       testing/mock_server_test.c.
+
+20260410
+
+       Tech debt: refactored tlsproxy PARAM, INIT and START send
+       and receive handlers to make the code easier to test, and
+       added some unit tests. This removes tls_proxy_client_misc.c,
+       tls_proxy_client_print.c, tls_proxy_client_scan.c,
+       tls_proxy_server_print.c, and tls_proxy_server_scan.c, after
+       redistributing their content to new files. Files:
+       postscreen/Makefile.in, smtpd/Makefile.in, smtp/Makefile.in,
+       tls/Makefile.in, tls_proxy.h, tls_proxy_attr.h,
+       tls_proxy_client_init_proto.c tls_proxy_client_init_proto.h,
+       tls_proxy_client_init_proto_test.c tls_proxy_client_param_proto.c,
+       tls_proxy_client_param_proto.h tls_proxy_client_param_proto_test.c,
+       tls_proxy_client_start_proto.c tls_proxy_client_start_proto.h,
+       tls_proxy_server_init_proto.c tls_proxy_server_init_proto.h,
+       tls_proxy_server_init_proto_test.c tls_proxy_server_param_proto.c,
+       tls_proxy_server_param_proto.h tls_proxy_server_param_proto_test.c,
+       tls_proxy_server_start_proto.c tls_proxy_server_start_proto.h.
+
+       Added missing tls_trust_server_ccerts parameter entry in
+       smtpd(8) manpage, missing tls_trust_server_ccerts parameter
+       support in postlink. Files: smtpd/smtpd.c, mantools/postlink.
+
 TODO
 
        Reorganize PTEST_LIB, PMOCK_LIB, TESTLIB, TESTLIBS, etc.
+
+       Document TLS parameters in tlsproxy(8) and postscreen(8).
index 59791412fb6ee5543d563c0c39576939a359c932..e3c5d759d185fd72f66f98d9307326682d5afdec 100644 (file)
@@ -857,8 +857,8 @@ address:
 
 The above basic RSA tests are expected to work, if the instructions are
 followed accurately. If there's an unexpected failure, and the reasons are
-unclear, see the debugging tutorial, for how seek help from the p\bpo\bos\bst\btf\bfi\bix\bx-\b-u\bus\bse\ber\brs\bs
-list.
+unclear, see the debugging tutorial, for how to ask for help on the p\bpo\bos\bst\btf\bfi\bix\bx-\b-
+u\bus\bse\ber\brs\blist.
 
 With the basic RSA test out of the way, let's try combining RSA and ECDSA keys:
 
@@ -985,7 +985,7 @@ algorithm needed for this test:
         # postconf -MX "127.0.0.1:$port/inet"
         # postfix reload
 
-If all went well, your OpenSSL runtime working SNI support for also for newer
+If all went well, your OpenSSL runtime has working SNI support also for newer
 public key algorithms, such as M\bML\bL-\b-D\bDS\bSA\bA. If the test failed, and the Postfix logs
 show that the test Postfix SMTP server failed with a segfault, your OpenSSL
 runtime has not yet been patched. The test is not viable with OpenSSL 3.4 or
index e5f8654dc700c30042ca91fab0bc4bfa77de66d1..8e7cdc2e7846ef1f604f7ebe805435ffc0f93ad6 100644 (file)
@@ -1169,7 +1169,7 @@ loopback IP address: </p>
 <p> The above basic RSA tests are expected to work, if the instructions
 are followed accurately.  If there's an unexpected failure, and the reasons
 are unclear, see the <a href="DEBUG_README.html#mail">debugging
-tutorial</a>, for how seek help from the <b>postfix-users</b> list. </p>
+tutorial</a>, for how to ask for help on the <b>postfix-users</b> list. </p>
 
 <p> With the basic RSA test out of the way, let's try combining RSA and
 ECDSA keys: </p>
@@ -1303,7 +1303,7 @@ the <b>ML-DSA</b> algorithm needed for this test: </p>
 </pre>
 </blockquote>
 
-<p> If all went well, your OpenSSL runtime working SNI support for also for
+<p> If all went well, your OpenSSL runtime has working SNI support also for
 newer public key algorithms, such as <b>ML-DSA</b>.  If the test failed, and
 the Postfix logs show that the test Postfix SMTP server failed with a
 segfault, your OpenSSL runtime has not yet been patched.  The test is not
index d4ae0a078a939d658c27ec5f4d178b1bff3970fc..b0516764692abae719e98fa04d92bc248eda7e01 100644 (file)
@@ -667,6 +667,11 @@ SMTPD(8)                                                              SMTPD(8)
               Record the ESMTP REQUIRETLS  request  in  a  "Require-TLS-ESMTP:
               yes" message header.
 
+       <b><a href="postconf.5.html#tls_trust_server_ccerts">tls_trust_server_ccerts</a> (no)</b>
+              Whether  to  trust  client certificates whose extended key usage
+              (EKU) lists only <b>serverAuth</b> and  not  <b>clientAuth</b>  as  valid  TLS
+              client certificates.
+
 <b><a name="obsolete_tls_controls">OBSOLETE TLS CONTROLS</a></b>
        The  following  configuration  parameters  exist for compatibility with
        Postfix versions before 2.3. Support for these will  be  removed  in  a
index 3b50146500aefe288d65f737ac9375babcd4f20c..349faf222c3e9c776e0b4d1a628cff9701230617 100644 (file)
@@ -587,6 +587,10 @@ FROM" command.
 .IP "\fBrequiretls_esmtp_header (yes)\fR"
 Record the ESMTP REQUIRETLS request in a "Require\-TLS\-ESMTP:
 yes" message header.
+.IP "\fBtls_trust_server_ccerts (no)\fR"
+Whether to trust client certificates whose extended key usage (EKU) lists
+only \fBserverAuth\fR and not \fBclientAuth\fR as valid TLS client
+certificates.
 .SH "OBSOLETE TLS CONTROLS"
 .na
 .nf
index c797672c366a0245377972b78a8c4b2e4500fddb..d7d78a128c2e5eb80ef206717ee7f85cd969aaac 100755 (executable)
@@ -815,6 +815,7 @@ while (<>) {
     s;\btls_dane_digest_agility\b;<a href="postconf.5.html#tls_dane_digest_agility">$&</a>;g;
     s;\btls_dane_trust_anchor_digest_enable\b;<a href="postconf.5.html#tls_dane_trust_anchor_digest_enable">$&</a>;g;
     s;\btls_fast_shutdown_enable\b;<a href="postconf.5.html#tls_fast_shutdown_enable">$&</a>;g;
+    s;\btls_trust_server_ccerts\b;<a href="postconf.5.html#tls_trust_server_ccerts">$&</a>;g;
 
     s;\bfrozen_delivered_to\b;<a href="postconf.5.html#frozen_delivered_to">$&</a>;g;
     s;\breset_owner_alias\b;<a href="postconf.5.html#reset_owner_alias">$&</a>;g;
index fefe0e807434c1b76a6afa5495a08600b8d3c443..4831aede77a44b82e114374c0086c8e17fa8479c 100644 (file)
@@ -1169,7 +1169,7 @@ loopback IP address: </p>
 <p> The above basic RSA tests are expected to work, if the instructions
 are followed accurately.  If there's an unexpected failure, and the reasons
 are unclear, see the <a href="DEBUG_README.html#mail">debugging
-tutorial</a>, for how seek help from the <b>postfix-users</b> list. </p>
+tutorial</a>, for how to ask for help on the <b>postfix-users</b> list. </p>
 
 <p> With the basic RSA test out of the way, let's try combining RSA and
 ECDSA keys: </p>
@@ -1303,7 +1303,7 @@ the <b>ML-DSA</b> algorithm needed for this test: </p>
 </pre>
 </blockquote>
 
-<p> If all went well, your OpenSSL runtime working SNI support for also for
+<p> If all went well, your OpenSSL runtime has working SNI support also for
 newer public key algorithms, such as <b>ML-DSA</b>.  If the test failed, and
 the Postfix logs show that the test Postfix SMTP server failed with a
 segfault, your OpenSSL runtime has not yet been patched.  The test is not
index 522a03470bdb0ba1cf7578713247f3d97dc1618f..0655242df94e6f88d59fc4a6f7adaaafe11b828c 100644 (file)
@@ -231,3 +231,4 @@ proto  proto stop proto stop double cc
  differ Files postalias postalias c local alias c 
  local local hc local Makefile 
  Dukhovni Files proto postconf proto proto TLS_README html 
+ tls tls h tls tls_misc c tls tls_server c 
index b800a34e75fd76d57cbcbe75e0c220b8958437ae..05a0afebbc504b329eedc09cf005d24d4673a2c6 100644 (file)
@@ -1972,3 +1972,7 @@ undoable
 EKU
 clientAuth
 serverAuth
+Bool
+HERMETICITY
+VPRINT
+deserializes
index 79b686472c29b0799ac6d7fb3b30df4658e86cc5..b3f4491bb81d11059030a18cfa747fae23a8b594 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20260406"
+#define MAIL_RELEASE_DATE      "20260410"
 #define MAIL_VERSION_NUMBER    "3.12"
 
 #ifdef SNAPSHOT
index 8f34f7db9cc8a9006a6b5e0c3e27890303d4af07..801b2ac0124045d14568c92a417e7e29e5fb4289 100644 (file)
@@ -405,6 +405,13 @@ postscreen_starttls.o: ../../include/stringops.h
 postscreen_starttls.o: ../../include/sys_defs.h
 postscreen_starttls.o: ../../include/tls.h
 postscreen_starttls.o: ../../include/tls_proxy.h
+postscreen_starttls.o: ../../include/tls_proxy_attr.h
+postscreen_starttls.o: ../../include/tls_proxy_client_init_proto.h
+postscreen_starttls.o: ../../include/tls_proxy_client_param_proto.h
+postscreen_starttls.o: ../../include/tls_proxy_client_start_proto.h
+postscreen_starttls.o: ../../include/tls_proxy_server_init_proto.h
+postscreen_starttls.o: ../../include/tls_proxy_server_param_proto.h
+postscreen_starttls.o: ../../include/tls_proxy_server_start_proto.h
 postscreen_starttls.o: ../../include/vbuf.h
 postscreen_starttls.o: ../../include/vstream.h
 postscreen_starttls.o: ../../include/vstring.h
index 1159a1100b5488332afac84c977ab71b6e735a73..83181852bc1f3885d00e2842adcdd7c048db51ba 100644 (file)
@@ -138,6 +138,13 @@ smtp.o: ../../include/stringops.h
 smtp.o: ../../include/sys_defs.h
 smtp.o: ../../include/tls.h
 smtp.o: ../../include/tls_proxy.h
+smtp.o: ../../include/tls_proxy_attr.h
+smtp.o: ../../include/tls_proxy_client_init_proto.h
+smtp.o: ../../include/tls_proxy_client_param_proto.h
+smtp.o: ../../include/tls_proxy_client_start_proto.h
+smtp.o: ../../include/tls_proxy_server_init_proto.h
+smtp.o: ../../include/tls_proxy_server_param_proto.h
+smtp.o: ../../include/tls_proxy_server_start_proto.h
 smtp.o: ../../include/tok822.h
 smtp.o: ../../include/vbuf.h
 smtp.o: ../../include/vstream.h
@@ -186,6 +193,13 @@ smtp_addr.o: ../../include/stringops.h
 smtp_addr.o: ../../include/sys_defs.h
 smtp_addr.o: ../../include/tls.h
 smtp_addr.o: ../../include/tls_proxy.h
+smtp_addr.o: ../../include/tls_proxy_attr.h
+smtp_addr.o: ../../include/tls_proxy_client_init_proto.h
+smtp_addr.o: ../../include/tls_proxy_client_param_proto.h
+smtp_addr.o: ../../include/tls_proxy_client_start_proto.h
+smtp_addr.o: ../../include/tls_proxy_server_init_proto.h
+smtp_addr.o: ../../include/tls_proxy_server_param_proto.h
+smtp_addr.o: ../../include/tls_proxy_server_start_proto.h
 smtp_addr.o: ../../include/tok822.h
 smtp_addr.o: ../../include/vbuf.h
 smtp_addr.o: ../../include/vstream.h
@@ -240,6 +254,13 @@ smtp_chat.o: ../../include/stringops.h
 smtp_chat.o: ../../include/sys_defs.h
 smtp_chat.o: ../../include/tls.h
 smtp_chat.o: ../../include/tls_proxy.h
+smtp_chat.o: ../../include/tls_proxy_attr.h
+smtp_chat.o: ../../include/tls_proxy_client_init_proto.h
+smtp_chat.o: ../../include/tls_proxy_client_param_proto.h
+smtp_chat.o: ../../include/tls_proxy_client_start_proto.h
+smtp_chat.o: ../../include/tls_proxy_server_init_proto.h
+smtp_chat.o: ../../include/tls_proxy_server_param_proto.h
+smtp_chat.o: ../../include/tls_proxy_server_start_proto.h
 smtp_chat.o: ../../include/tok822.h
 smtp_chat.o: ../../include/vbuf.h
 smtp_chat.o: ../../include/vstream.h
@@ -294,6 +315,13 @@ smtp_connect.o: ../../include/sys_defs.h
 smtp_connect.o: ../../include/timed_connect.h
 smtp_connect.o: ../../include/tls.h
 smtp_connect.o: ../../include/tls_proxy.h
+smtp_connect.o: ../../include/tls_proxy_attr.h
+smtp_connect.o: ../../include/tls_proxy_client_init_proto.h
+smtp_connect.o: ../../include/tls_proxy_client_param_proto.h
+smtp_connect.o: ../../include/tls_proxy_client_start_proto.h
+smtp_connect.o: ../../include/tls_proxy_server_init_proto.h
+smtp_connect.o: ../../include/tls_proxy_server_param_proto.h
+smtp_connect.o: ../../include/tls_proxy_server_start_proto.h
 smtp_connect.o: ../../include/tok822.h
 smtp_connect.o: ../../include/valid_hostname.h
 smtp_connect.o: ../../include/vbuf.h
@@ -339,6 +367,13 @@ smtp_key.o: ../../include/string_list.h
 smtp_key.o: ../../include/sys_defs.h
 smtp_key.o: ../../include/tls.h
 smtp_key.o: ../../include/tls_proxy.h
+smtp_key.o: ../../include/tls_proxy_attr.h
+smtp_key.o: ../../include/tls_proxy_client_init_proto.h
+smtp_key.o: ../../include/tls_proxy_client_param_proto.h
+smtp_key.o: ../../include/tls_proxy_client_start_proto.h
+smtp_key.o: ../../include/tls_proxy_server_init_proto.h
+smtp_key.o: ../../include/tls_proxy_server_param_proto.h
+smtp_key.o: ../../include/tls_proxy_server_start_proto.h
 smtp_key.o: ../../include/tok822.h
 smtp_key.o: ../../include/vbuf.h
 smtp_key.o: ../../include/vstream.h
@@ -382,6 +417,13 @@ smtp_map11.o: ../../include/string_list.h
 smtp_map11.o: ../../include/sys_defs.h
 smtp_map11.o: ../../include/tls.h
 smtp_map11.o: ../../include/tls_proxy.h
+smtp_map11.o: ../../include/tls_proxy_attr.h
+smtp_map11.o: ../../include/tls_proxy_client_init_proto.h
+smtp_map11.o: ../../include/tls_proxy_client_param_proto.h
+smtp_map11.o: ../../include/tls_proxy_client_start_proto.h
+smtp_map11.o: ../../include/tls_proxy_server_init_proto.h
+smtp_map11.o: ../../include/tls_proxy_server_param_proto.h
+smtp_map11.o: ../../include/tls_proxy_server_start_proto.h
 smtp_map11.o: ../../include/tok822.h
 smtp_map11.o: ../../include/vbuf.h
 smtp_map11.o: ../../include/vstream.h
@@ -425,6 +467,13 @@ smtp_misc.o: ../../include/string_list.h
 smtp_misc.o: ../../include/sys_defs.h
 smtp_misc.o: ../../include/tls.h
 smtp_misc.o: ../../include/tls_proxy.h
+smtp_misc.o: ../../include/tls_proxy_attr.h
+smtp_misc.o: ../../include/tls_proxy_client_init_proto.h
+smtp_misc.o: ../../include/tls_proxy_client_param_proto.h
+smtp_misc.o: ../../include/tls_proxy_client_start_proto.h
+smtp_misc.o: ../../include/tls_proxy_server_init_proto.h
+smtp_misc.o: ../../include/tls_proxy_server_param_proto.h
+smtp_misc.o: ../../include/tls_proxy_server_start_proto.h
 smtp_misc.o: ../../include/tok822.h
 smtp_misc.o: ../../include/vbuf.h
 smtp_misc.o: ../../include/vstream.h
@@ -488,6 +537,13 @@ smtp_proto.o: ../../include/stringops.h
 smtp_proto.o: ../../include/sys_defs.h
 smtp_proto.o: ../../include/tls.h
 smtp_proto.o: ../../include/tls_proxy.h
+smtp_proto.o: ../../include/tls_proxy_attr.h
+smtp_proto.o: ../../include/tls_proxy_client_init_proto.h
+smtp_proto.o: ../../include/tls_proxy_client_param_proto.h
+smtp_proto.o: ../../include/tls_proxy_client_start_proto.h
+smtp_proto.o: ../../include/tls_proxy_server_init_proto.h
+smtp_proto.o: ../../include/tls_proxy_server_param_proto.h
+smtp_proto.o: ../../include/tls_proxy_server_start_proto.h
 smtp_proto.o: ../../include/tlsrpt_wrapper.h
 smtp_proto.o: ../../include/tok822.h
 smtp_proto.o: ../../include/uxtext.h
@@ -538,6 +594,13 @@ smtp_rcpt.o: ../../include/stringops.h
 smtp_rcpt.o: ../../include/sys_defs.h
 smtp_rcpt.o: ../../include/tls.h
 smtp_rcpt.o: ../../include/tls_proxy.h
+smtp_rcpt.o: ../../include/tls_proxy_attr.h
+smtp_rcpt.o: ../../include/tls_proxy_client_init_proto.h
+smtp_rcpt.o: ../../include/tls_proxy_client_param_proto.h
+smtp_rcpt.o: ../../include/tls_proxy_client_start_proto.h
+smtp_rcpt.o: ../../include/tls_proxy_server_init_proto.h
+smtp_rcpt.o: ../../include/tls_proxy_server_param_proto.h
+smtp_rcpt.o: ../../include/tls_proxy_server_start_proto.h
 smtp_rcpt.o: ../../include/tok822.h
 smtp_rcpt.o: ../../include/vbuf.h
 smtp_rcpt.o: ../../include/vstream.h
@@ -605,6 +668,13 @@ smtp_reuse.o: ../../include/stringops.h
 smtp_reuse.o: ../../include/sys_defs.h
 smtp_reuse.o: ../../include/tls.h
 smtp_reuse.o: ../../include/tls_proxy.h
+smtp_reuse.o: ../../include/tls_proxy_attr.h
+smtp_reuse.o: ../../include/tls_proxy_client_init_proto.h
+smtp_reuse.o: ../../include/tls_proxy_client_param_proto.h
+smtp_reuse.o: ../../include/tls_proxy_client_start_proto.h
+smtp_reuse.o: ../../include/tls_proxy_server_init_proto.h
+smtp_reuse.o: ../../include/tls_proxy_server_param_proto.h
+smtp_reuse.o: ../../include/tls_proxy_server_start_proto.h
 smtp_reuse.o: ../../include/tok822.h
 smtp_reuse.o: ../../include/vbuf.h
 smtp_reuse.o: ../../include/vstream.h
@@ -650,6 +720,13 @@ smtp_sasl_auth_cache.o: ../../include/stringops.h
 smtp_sasl_auth_cache.o: ../../include/sys_defs.h
 smtp_sasl_auth_cache.o: ../../include/tls.h
 smtp_sasl_auth_cache.o: ../../include/tls_proxy.h
+smtp_sasl_auth_cache.o: ../../include/tls_proxy_attr.h
+smtp_sasl_auth_cache.o: ../../include/tls_proxy_client_init_proto.h
+smtp_sasl_auth_cache.o: ../../include/tls_proxy_client_param_proto.h
+smtp_sasl_auth_cache.o: ../../include/tls_proxy_client_start_proto.h
+smtp_sasl_auth_cache.o: ../../include/tls_proxy_server_init_proto.h
+smtp_sasl_auth_cache.o: ../../include/tls_proxy_server_param_proto.h
+smtp_sasl_auth_cache.o: ../../include/tls_proxy_server_start_proto.h
 smtp_sasl_auth_cache.o: ../../include/tok822.h
 smtp_sasl_auth_cache.o: ../../include/vbuf.h
 smtp_sasl_auth_cache.o: ../../include/vstream.h
@@ -696,6 +773,13 @@ smtp_sasl_glue.o: ../../include/stringops.h
 smtp_sasl_glue.o: ../../include/sys_defs.h
 smtp_sasl_glue.o: ../../include/tls.h
 smtp_sasl_glue.o: ../../include/tls_proxy.h
+smtp_sasl_glue.o: ../../include/tls_proxy_attr.h
+smtp_sasl_glue.o: ../../include/tls_proxy_client_init_proto.h
+smtp_sasl_glue.o: ../../include/tls_proxy_client_param_proto.h
+smtp_sasl_glue.o: ../../include/tls_proxy_client_start_proto.h
+smtp_sasl_glue.o: ../../include/tls_proxy_server_init_proto.h
+smtp_sasl_glue.o: ../../include/tls_proxy_server_param_proto.h
+smtp_sasl_glue.o: ../../include/tls_proxy_server_start_proto.h
 smtp_sasl_glue.o: ../../include/tok822.h
 smtp_sasl_glue.o: ../../include/vbuf.h
 smtp_sasl_glue.o: ../../include/vstream.h
@@ -741,6 +825,13 @@ smtp_sasl_proto.o: ../../include/stringops.h
 smtp_sasl_proto.o: ../../include/sys_defs.h
 smtp_sasl_proto.o: ../../include/tls.h
 smtp_sasl_proto.o: ../../include/tls_proxy.h
+smtp_sasl_proto.o: ../../include/tls_proxy_attr.h
+smtp_sasl_proto.o: ../../include/tls_proxy_client_init_proto.h
+smtp_sasl_proto.o: ../../include/tls_proxy_client_param_proto.h
+smtp_sasl_proto.o: ../../include/tls_proxy_client_start_proto.h
+smtp_sasl_proto.o: ../../include/tls_proxy_server_init_proto.h
+smtp_sasl_proto.o: ../../include/tls_proxy_server_param_proto.h
+smtp_sasl_proto.o: ../../include/tls_proxy_server_start_proto.h
 smtp_sasl_proto.o: ../../include/tok822.h
 smtp_sasl_proto.o: ../../include/vbuf.h
 smtp_sasl_proto.o: ../../include/vstream.h
@@ -784,6 +875,13 @@ smtp_session.o: ../../include/stringops.h
 smtp_session.o: ../../include/sys_defs.h
 smtp_session.o: ../../include/tls.h
 smtp_session.o: ../../include/tls_proxy.h
+smtp_session.o: ../../include/tls_proxy_attr.h
+smtp_session.o: ../../include/tls_proxy_client_init_proto.h
+smtp_session.o: ../../include/tls_proxy_client_param_proto.h
+smtp_session.o: ../../include/tls_proxy_client_start_proto.h
+smtp_session.o: ../../include/tls_proxy_server_init_proto.h
+smtp_session.o: ../../include/tls_proxy_server_param_proto.h
+smtp_session.o: ../../include/tls_proxy_server_start_proto.h
 smtp_session.o: ../../include/tok822.h
 smtp_session.o: ../../include/vbuf.h
 smtp_session.o: ../../include/vstream.h
@@ -826,6 +924,13 @@ smtp_state.o: ../../include/string_list.h
 smtp_state.o: ../../include/sys_defs.h
 smtp_state.o: ../../include/tls.h
 smtp_state.o: ../../include/tls_proxy.h
+smtp_state.o: ../../include/tls_proxy_attr.h
+smtp_state.o: ../../include/tls_proxy_client_init_proto.h
+smtp_state.o: ../../include/tls_proxy_client_param_proto.h
+smtp_state.o: ../../include/tls_proxy_client_start_proto.h
+smtp_state.o: ../../include/tls_proxy_server_init_proto.h
+smtp_state.o: ../../include/tls_proxy_server_param_proto.h
+smtp_state.o: ../../include/tls_proxy_server_start_proto.h
 smtp_state.o: ../../include/tlsrpt_wrapper.h
 smtp_state.o: ../../include/tok822.h
 smtp_state.o: ../../include/vbuf.h
@@ -872,6 +977,13 @@ smtp_tls_policy.o: ../../include/stringops.h
 smtp_tls_policy.o: ../../include/sys_defs.h
 smtp_tls_policy.o: ../../include/tls.h
 smtp_tls_policy.o: ../../include/tls_proxy.h
+smtp_tls_policy.o: ../../include/tls_proxy_attr.h
+smtp_tls_policy.o: ../../include/tls_proxy_client_init_proto.h
+smtp_tls_policy.o: ../../include/tls_proxy_client_param_proto.h
+smtp_tls_policy.o: ../../include/tls_proxy_client_start_proto.h
+smtp_tls_policy.o: ../../include/tls_proxy_server_init_proto.h
+smtp_tls_policy.o: ../../include/tls_proxy_server_param_proto.h
+smtp_tls_policy.o: ../../include/tls_proxy_server_start_proto.h
 smtp_tls_policy.o: ../../include/tlsrpt_wrapper.h
 smtp_tls_policy.o: ../../include/tok822.h
 smtp_tls_policy.o: ../../include/valid_hostname.h
@@ -917,6 +1029,13 @@ smtp_tls_policy_test.o: ../../include/stringops.h
 smtp_tls_policy_test.o: ../../include/sys_defs.h
 smtp_tls_policy_test.o: ../../include/tls.h
 smtp_tls_policy_test.o: ../../include/tls_proxy.h
+smtp_tls_policy_test.o: ../../include/tls_proxy_attr.h
+smtp_tls_policy_test.o: ../../include/tls_proxy_client_init_proto.h
+smtp_tls_policy_test.o: ../../include/tls_proxy_client_param_proto.h
+smtp_tls_policy_test.o: ../../include/tls_proxy_client_start_proto.h
+smtp_tls_policy_test.o: ../../include/tls_proxy_server_init_proto.h
+smtp_tls_policy_test.o: ../../include/tls_proxy_server_param_proto.h
+smtp_tls_policy_test.o: ../../include/tls_proxy_server_start_proto.h
 smtp_tls_policy_test.o: ../../include/tok822.h
 smtp_tls_policy_test.o: ../../include/vbuf.h
 smtp_tls_policy_test.o: ../../include/vstream.h
@@ -960,6 +1079,13 @@ smtp_tlsrpt.o: ../../include/stringops.h
 smtp_tlsrpt.o: ../../include/sys_defs.h
 smtp_tlsrpt.o: ../../include/tls.h
 smtp_tlsrpt.o: ../../include/tls_proxy.h
+smtp_tlsrpt.o: ../../include/tls_proxy_attr.h
+smtp_tlsrpt.o: ../../include/tls_proxy_client_init_proto.h
+smtp_tlsrpt.o: ../../include/tls_proxy_client_param_proto.h
+smtp_tlsrpt.o: ../../include/tls_proxy_client_start_proto.h
+smtp_tlsrpt.o: ../../include/tls_proxy_server_init_proto.h
+smtp_tlsrpt.o: ../../include/tls_proxy_server_param_proto.h
+smtp_tlsrpt.o: ../../include/tls_proxy_server_start_proto.h
 smtp_tlsrpt.o: ../../include/tlsrpt_wrapper.h
 smtp_tlsrpt.o: ../../include/tok822.h
 smtp_tlsrpt.o: ../../include/vbuf.h
@@ -1007,6 +1133,13 @@ smtp_trouble.o: ../../include/stringops.h
 smtp_trouble.o: ../../include/sys_defs.h
 smtp_trouble.o: ../../include/tls.h
 smtp_trouble.o: ../../include/tls_proxy.h
+smtp_trouble.o: ../../include/tls_proxy_attr.h
+smtp_trouble.o: ../../include/tls_proxy_client_init_proto.h
+smtp_trouble.o: ../../include/tls_proxy_client_param_proto.h
+smtp_trouble.o: ../../include/tls_proxy_client_start_proto.h
+smtp_trouble.o: ../../include/tls_proxy_server_init_proto.h
+smtp_trouble.o: ../../include/tls_proxy_server_param_proto.h
+smtp_trouble.o: ../../include/tls_proxy_server_start_proto.h
 smtp_trouble.o: ../../include/tok822.h
 smtp_trouble.o: ../../include/vbuf.h
 smtp_trouble.o: ../../include/vstream.h
@@ -1047,6 +1180,13 @@ smtp_unalias.o: ../../include/string_list.h
 smtp_unalias.o: ../../include/sys_defs.h
 smtp_unalias.o: ../../include/tls.h
 smtp_unalias.o: ../../include/tls_proxy.h
+smtp_unalias.o: ../../include/tls_proxy_attr.h
+smtp_unalias.o: ../../include/tls_proxy_client_init_proto.h
+smtp_unalias.o: ../../include/tls_proxy_client_param_proto.h
+smtp_unalias.o: ../../include/tls_proxy_client_start_proto.h
+smtp_unalias.o: ../../include/tls_proxy_server_init_proto.h
+smtp_unalias.o: ../../include/tls_proxy_server_param_proto.h
+smtp_unalias.o: ../../include/tls_proxy_server_start_proto.h
 smtp_unalias.o: ../../include/tok822.h
 smtp_unalias.o: ../../include/vbuf.h
 smtp_unalias.o: ../../include/vstream.h
index 4f5e2f988223578ad789ccdcb4d9017de88942ab..2b9e4703ded7db5fea2169cba9e06b3e7c9c4f41 100644 (file)
@@ -297,6 +297,13 @@ smtpd.o: ../../include/stringops.h
 smtpd.o: ../../include/sys_defs.h
 smtpd.o: ../../include/tls.h
 smtpd.o: ../../include/tls_proxy.h
+smtpd.o: ../../include/tls_proxy_attr.h
+smtpd.o: ../../include/tls_proxy_client_init_proto.h
+smtpd.o: ../../include/tls_proxy_client_param_proto.h
+smtpd.o: ../../include/tls_proxy_client_start_proto.h
+smtpd.o: ../../include/tls_proxy_server_init_proto.h
+smtpd.o: ../../include/tls_proxy_server_param_proto.h
+smtpd.o: ../../include/tls_proxy_server_start_proto.h
 smtpd.o: ../../include/tok822.h
 smtpd.o: ../../include/uxtext.h
 smtpd.o: ../../include/valid_hostname.h
index 5cf24780893bd531b7aff4f5e2b8bc31f8798edb..8e6b1558d1c080ad4330b348b5351bf5c56252a8 100644 (file)
 /* .IP "\fBrequiretls_esmtp_header (yes)\fR"
 /*     Record the ESMTP REQUIRETLS request in a "Require-TLS-ESMTP:
 /*     yes" message header.
+/* .IP "\fBtls_trust_server_ccerts (no)\fR"
+/*     Whether to trust client certificates whose extended key usage (EKU) lists
+/*     only \fBserverAuth\fR and not \fBclientAuth\fR as valid TLS client
+/*     certificates.
 /* OBSOLETE TLS CONTROLS
 /* .ad
 /* .fi
index 1fd944b761835f6146ab82b93762a49566ce3ae1..dd332092f98cdcd383364754352657c174ff5776 100644 (file)
@@ -6,10 +6,10 @@
 /* SYNOPSIS
 /*     #include <make_attr.h>
 /*
-/*     VSTRING *make_attr(int flags, ...)
+/*     VSTRING *make_attr(ATTR_VPRINT_COMMON_FN vprint_fn, int flags, ...)
 /* DESCRIPTION
 /*     make_attr() creates a serialized request or response attribute
-/*     list. The arguments are like attr_print().
+/*     list. The flags and following arguments are like attr_print().
 /* LICENSE
 /* .ad
 /* .fi
@@ -19,6 +19,9 @@
 /*     Google, Inc.
 /*     111 8th Avenue
 /*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
  /*
@@ -41,7 +44,7 @@
 
 /* make_attr - serialize attribute list */
 
-VSTRING *make_attr(int flags,...)
+VSTRING *make_attr(ATTR_VPRINT_COMMON_FN vprint_fn, int flags, ...)
 {
     static const char myname[] = "make_attr";
     VSTRING *res = vstring_alloc(100);
@@ -52,7 +55,7 @@ VSTRING *make_attr(int flags,...)
     if ((stream = vstream_memopen(res, O_WRONLY)) == 0)
        ptest_fatal(ptest_ctx_current(), "%s: vstream_memopen: %m", myname);;
     va_start(ap, flags);
-    err = attr_vprint(stream, flags, ap);
+    err = vprint_fn(stream, flags, ap);
     va_end(ap);
     if (vstream_fclose(stream) != 0 || err)
        ptest_fatal(ptest_ctx_current(), "%s: write attributes: %m", myname);
index 97659d901a37ffa30adf63efc8039c28ceb94ef9..b424a259a5f37327d781351db41327542640b3f3 100644 (file)
@@ -19,7 +19,7 @@
  /*
   * External interface.
   */
-extern VSTRING *make_attr(int,...);
+extern VSTRING *make_attr(ATTR_VPRINT_COMMON_FN, int,...);
 
 /* LICENSE
 /* .ad
index c9fb5405b13e54ebfd0e6a013ce8cc25d4c4feb9..3cd6f719b3da65af9b590bd4bea89652420279d3 100644 (file)
@@ -33,7 +33,7 @@ static void test_eq_attr_equal(PTEST_CTX *t, const PTEST_CASE *unused)
     /*
      * Serialize some attributes.
      */
-    want_attr = make_attr(ATTR_FLAG_NONE,
+    want_attr = make_attr(attr_vprint, ATTR_FLAG_NONE,
                          SEND_ATTR_STR("this-key", "this-value"),
                          SEND_ATTR_STR("that-key", "that-value"),
                          ATTR_TYPE_END);
@@ -58,11 +58,11 @@ static void test_eq_attr_swapped(PTEST_CTX *t, const PTEST_CASE *unused)
     /*
      * Serialize some attributes.
      */
-    want_attr = make_attr(ATTR_FLAG_NONE,
+    want_attr = make_attr(attr_vprint, ATTR_FLAG_NONE,
                          SEND_ATTR_STR("this-key", "this-value"),
                          SEND_ATTR_STR("that-key", "that-value"),
                          ATTR_TYPE_END);
-    swapped_attr = make_attr(ATTR_FLAG_NONE,
+    swapped_attr = make_attr(attr_vprint, ATTR_FLAG_NONE,
                             SEND_ATTR_STR("that-key", "that-value"),
                             SEND_ATTR_STR("this-key", "this-value"),
                             ATTR_TYPE_END);
@@ -88,12 +88,12 @@ static void test_eq_attr_diff(PTEST_CTX *t, const PTEST_CASE *unused)
     /*
      * Serialize some attributes.
      */
-    want_attr = make_attr(ATTR_FLAG_NONE,
+    want_attr = make_attr(attr_vprint, ATTR_FLAG_NONE,
                          SEND_ATTR_STR("this-key", "this-value"),
                          SEND_ATTR_STR("that-key", "that-value"),
                          SEND_ATTR_STR("same-key", "same-value"),
                          ATTR_TYPE_END);
-    swapped_attr = make_attr(ATTR_FLAG_NONE,
+    swapped_attr = make_attr(attr_vprint, ATTR_FLAG_NONE,
                             SEND_ATTR_STR("not-this-key", "this-value"),
                             SEND_ATTR_STR("that-key", "not-that-value"),
                             SEND_ATTR_STR("same-key", "same-value"),
index e334d05f06a98d1af97b2ef97e5f02b2219d808c..2f22ec43bedbe7a9a3a710e57dee4230fb13a1d2 100644 (file)
@@ -119,11 +119,11 @@ static void test_single_server(PTEST_CTX *t, const PTEST_CASE *tp)
      * Set up a server request expectation, and response.
      */
     serialized_req =
-       make_attr(ATTR_FLAG_NONE,
+       make_attr(attr_vprint, ATTR_FLAG_NONE,
                  SEND_ATTR_STR(MAIL_ATTR_REQ, REQUEST_VAL),
                  ATTR_TYPE_END);
     serialized_resp =
-       make_attr(ATTR_FLAG_NONE,
+       make_attr(attr_vprint, ATTR_FLAG_NONE,
                  SEND_ATTR_STR(MAIL_ATTR_REQ, REQUEST_VAL),
                  SEND_ATTR_INT(MAIL_ATTR_SIZE, strlen(REQUEST_VAL)),
                  ATTR_TYPE_END);
@@ -195,11 +195,11 @@ static void test_request_mismatch(PTEST_CTX *t, const PTEST_CASE *tp)
      * Set up a server request expectation, and response.
      */
     serialized_req =
-       make_attr(ATTR_FLAG_NONE,
+       make_attr(attr_vprint, ATTR_FLAG_NONE,
                  SEND_ATTR_STR(MAIL_ATTR_REQ, REQUEST_VAL "g"),
                  ATTR_TYPE_END);
     serialized_resp =
-       make_attr(ATTR_FLAG_NONE,
+       make_attr(attr_vprint, ATTR_FLAG_NONE,
                  SEND_ATTR_STR(MAIL_ATTR_REQ, REQUEST_VAL),
                  SEND_ATTR_INT(MAIL_ATTR_SIZE, strlen(REQUEST_VAL)),
                  ATTR_TYPE_END);
@@ -306,7 +306,7 @@ static void test_server_speaks_only(PTEST_CTX *t, const PTEST_CASE *tp)
      * Set up a server response, without request expectation.
      */
     serialized_resp =
-       make_attr(ATTR_FLAG_NONE,
+       make_attr(attr_vprint, ATTR_FLAG_NONE,
                  SEND_ATTR_STR(MAIL_ATTR_REQ, REQUEST_VAL),
                  SEND_ATTR_INT(MAIL_ATTR_SIZE, strlen(REQUEST_VAL)),
                  ATTR_TYPE_END);
@@ -367,7 +367,7 @@ static void test_client_speaks_only(PTEST_CTX *t, const PTEST_CASE *tp)
      * Set up a server request expectation, and response.
      */
     serialized_req =
-       make_attr(ATTR_FLAG_NONE,
+       make_attr(attr_vprint, ATTR_FLAG_NONE,
                  SEND_ATTR_STR(MAIL_ATTR_REQ, REQUEST_VAL),
                  ATTR_TYPE_END);
     mock_server_interact(mp, serialized_req, NO_RESPONSE);
index 328e25ae486306ab9f7d953df4e49ddf9dc11bf9..aa11f78fdff393c78d3514742c506cb26c89bd08 100644 (file)
@@ -5,27 +5,46 @@ SRCS  = tls_prng_dev.c tls_prng_egd.c tls_prng_file.c tls_fprint.c \
        tls_client.c tls_server.c tls_scache.c tls_mgr.c tls_seed.c \
        tls_level.c \
        tls_proxy_clnt.c tls_proxy_context_print.c tls_proxy_context_scan.c \
-       tls_proxy_client_init_print.c tls_proxy_client_init_scan.c \
-       tls_proxy_server_init_print.c tls_proxy_server_init_scan.c \
-       tls_proxy_client_start_print.c tls_proxy_client_start_scan.c \
-       tls_proxy_server_start_print.c tls_proxy_server_start_scan.c \
-       tls_proxy_client_misc.c tlsrpt_wrapper.c
+       tlsrpt_wrapper.c \
+       tls_proxy_client_param_proto.c \
+       tls_proxy_client_init_proto.c \
+       tls_proxy_client_start_proto.c \
+       tls_proxy_server_param_proto.c \
+       tls_proxy_server_init_proto.c \
+       tls_proxy_server_start_proto.c
 OBJS   = tls_prng_dev.o tls_prng_egd.o tls_prng_file.o tls_fprint.o \
        tls_prng_exch.o tls_stream.o tls_bio_ops.o tls_misc.o tls_dh.o \
        tls_verify.o tls_dane.o tls_certkey.o tls_session.o \
        tls_client.o tls_server.o tls_scache.o tls_mgr.o tls_seed.o \
        tls_level.o \
        tls_proxy_clnt.o tls_proxy_context_print.o tls_proxy_context_scan.o \
-       tls_proxy_client_print.o tls_proxy_client_scan.o \
-       tls_proxy_server_print.o tls_proxy_server_scan.o \
-       tls_proxy_client_misc.o tlsrpt_wrapper.o
-HDRS   = tls.h tls_prng.h tls_scache.h tls_mgr.h tls_proxy.h tlsrpt_wrapper.h
-TESTSRC        = 
+       tlsrpt_wrapper.o \
+       tls_proxy_client_param_proto.o \
+       tls_proxy_client_init_proto.o \
+       tls_proxy_client_start_proto.o \
+       tls_proxy_server_param_proto.o \
+       tls_proxy_server_init_proto.o \
+       tls_proxy_server_start_proto.o
+HDRS   = tls.h tls_prng.h tls_scache.h tls_mgr.h tls_proxy.h tlsrpt_wrapper.h \
+       tls_proxy_attr.h \
+       tls_proxy_client_param_proto.h \
+       tls_proxy_client_init_proto.h \
+       tls_proxy_client_start_proto.h \
+       tls_proxy_server_param_proto.h \
+       tls_proxy_server_init_proto.h \
+       tls_proxy_server_start_proto.h
+TESTSRC        = tls_proxy_client_param_proto_test.c tls_proxy_client_init_proto_test.c \
+       tls_proxy_server_param_proto_test.c tls_proxy_server_init_proto_test.c
+TESTOBJ        = tls_proxy_client_param_proto_test.o tls_proxy_client_init_proto_test.o \
+       tls_proxy_server_param_proto_test.o tls_proxy_server_init_proto_test.o
 DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE)
 CFLAGS = $(DEBUG) $(OPT) $(DEFS)
 INCL   =
 LIB    = lib$(LIB_PREFIX)tls$(LIB_SUFFIX)
-TESTPROG= tls_dh tls_mgr tls_dane tls_certkey
+TESTPROG= tls_dh tls_mgr tls_dane tls_certkey \
+       tls_proxy_client_param_proto_test tls_proxy_client_init_proto_test \
+       tls_proxy_server_param_proto_test tls_proxy_server_init_proto_test
+TESTLIBS= $(LIB_DIR)/libtesting.a $(LIB_DIR)/libptest.a
 
 LIBS   = ../../lib/lib$(LIB_PREFIX)dns$(LIB_SUFFIX) \
        ../../lib/lib$(LIB_PREFIX)global$(LIB_SUFFIX) \
@@ -38,14 +57,32 @@ MAKES       =
 
 all: $(LIB)
 
-$(OBJS): ../../conf/makedefs.out
+$(OBJS) $(TESTOBJ): ../../conf/makedefs.out
 
 Makefile: Makefile.in
        cat ../../conf/makedefs.out $? >$@
 
 test:  $(TESTPROG)
 
-tests: tls_certkey_tests tls_dane_tests
+tls_proxy_client_param_proto_test: update tls_proxy_client_param_proto_test.o \
+           $(TESTLIBS) $(LIB) $(LIBS)
+       $(CC) $(CFLAGS) -o $@ $@.o $(TESTLIBS) $(LIB) $(LIBS)
+
+tls_proxy_client_init_proto_test: update tls_proxy_client_init_proto_test.o \
+           $(TESTLIBS) $(LIB) $(LIBS)
+       $(CC) $(CFLAGS) -o $@ $@.o $(TESTLIBS) $(LIB) $(LIBS)
+
+tls_proxy_server_param_proto_test: update tls_proxy_server_param_proto_test.o \
+           $(TESTLIBS) $(LIB) $(LIBS)
+       $(CC) $(CFLAGS) -o $@ $@.o $(TESTLIBS) $(LIB) $(LIBS)
+
+tls_proxy_server_init_proto_test: update tls_proxy_server_init_proto_test.o \
+           $(TESTLIBS) $(LIB) $(LIBS)
+       $(CC) $(CFLAGS) -o $@ $@.o $(TESTLIBS) $(LIB) $(LIBS)
+
+tests: tls_certkey_tests tls_dane_tests \
+       test_tls_proxy_client_param_proto test_tls_proxy_client_init_proto \
+       test_tls_proxy_server_param_proto test_tls_proxy_server_init_proto
 
 tls_certkey_tests: test
        @echo Testing loading of keys and certs
@@ -79,6 +116,18 @@ tls_certkey_tests: test
 tls_dane_tests: tls_dane tls_dane.sh
        $(SHLIB_ENV) $(VALGRIND) bash tls_dane.sh
 
+test_tls_proxy_client_param_proto: tls_proxy_client_param_proto_test
+       $(SHLIB_ENV) $(VALGRIND)  ./tls_proxy_client_param_proto_test
+
+test_tls_proxy_client_init_proto: tls_proxy_client_init_proto_test
+       $(SHLIB_ENV) $(VALGRIND)  ./tls_proxy_client_init_proto_test
+
+test_tls_proxy_server_param_proto: tls_proxy_server_param_proto_test
+       $(SHLIB_ENV) $(VALGRIND)  ./tls_proxy_server_param_proto_test
+
+test_tls_proxy_server_init_proto: tls_proxy_server_init_proto_test
+       $(SHLIB_ENV) $(VALGRIND)  ./tls_proxy_server_init_proto_test
+
 root_tests:
 
 $(LIB):        $(OBJS)
@@ -329,70 +378,135 @@ tls_prng_file.o: ../../include/mymalloc.h
 tls_prng_file.o: ../../include/sys_defs.h
 tls_prng_file.o: tls_prng.h
 tls_prng_file.o: tls_prng_file.c
-tls_proxy_client_misc.o: ../../include/argv.h
-tls_proxy_client_misc.o: ../../include/attr.h
-tls_proxy_client_misc.o: ../../include/check_arg.h
-tls_proxy_client_misc.o: ../../include/dns.h
-tls_proxy_client_misc.o: ../../include/htable.h
-tls_proxy_client_misc.o: ../../include/mail_params.h
-tls_proxy_client_misc.o: ../../include/msg.h
-tls_proxy_client_misc.o: ../../include/myaddrinfo.h
-tls_proxy_client_misc.o: ../../include/mymalloc.h
-tls_proxy_client_misc.o: ../../include/name_code.h
-tls_proxy_client_misc.o: ../../include/name_mask.h
-tls_proxy_client_misc.o: ../../include/nvtable.h
-tls_proxy_client_misc.o: ../../include/sock_addr.h
-tls_proxy_client_misc.o: ../../include/sys_defs.h
-tls_proxy_client_misc.o: ../../include/vbuf.h
-tls_proxy_client_misc.o: ../../include/vstream.h
-tls_proxy_client_misc.o: ../../include/vstring.h
-tls_proxy_client_misc.o: tls.h
-tls_proxy_client_misc.o: tls_proxy.h
-tls_proxy_client_misc.o: tls_proxy_client_misc.c
-tls_proxy_client_print.o: ../../include/argv.h
-tls_proxy_client_print.o: ../../include/argv_attr.h
-tls_proxy_client_print.o: ../../include/attr.h
-tls_proxy_client_print.o: ../../include/check_arg.h
-tls_proxy_client_print.o: ../../include/dns.h
-tls_proxy_client_print.o: ../../include/htable.h
-tls_proxy_client_print.o: ../../include/mail_params.h
-tls_proxy_client_print.o: ../../include/msg.h
-tls_proxy_client_print.o: ../../include/myaddrinfo.h
-tls_proxy_client_print.o: ../../include/mymalloc.h
-tls_proxy_client_print.o: ../../include/name_code.h
-tls_proxy_client_print.o: ../../include/name_mask.h
-tls_proxy_client_print.o: ../../include/nvtable.h
-tls_proxy_client_print.o: ../../include/sock_addr.h
-tls_proxy_client_print.o: ../../include/sys_defs.h
-tls_proxy_client_print.o: ../../include/vbuf.h
-tls_proxy_client_print.o: ../../include/vstream.h
-tls_proxy_client_print.o: ../../include/vstring.h
-tls_proxy_client_print.o: tls.h
-tls_proxy_client_print.o: tls_proxy.h
-tls_proxy_client_print.o: tls_proxy_client_print.c
-tls_proxy_client_print.o: tlsrpt_wrapper.h
-tls_proxy_client_scan.o: ../../include/argv.h
-tls_proxy_client_scan.o: ../../include/argv_attr.h
-tls_proxy_client_scan.o: ../../include/attr.h
-tls_proxy_client_scan.o: ../../include/check_arg.h
-tls_proxy_client_scan.o: ../../include/dns.h
-tls_proxy_client_scan.o: ../../include/htable.h
-tls_proxy_client_scan.o: ../../include/mail_params.h
-tls_proxy_client_scan.o: ../../include/msg.h
-tls_proxy_client_scan.o: ../../include/myaddrinfo.h
-tls_proxy_client_scan.o: ../../include/mymalloc.h
-tls_proxy_client_scan.o: ../../include/name_code.h
-tls_proxy_client_scan.o: ../../include/name_mask.h
-tls_proxy_client_scan.o: ../../include/nvtable.h
-tls_proxy_client_scan.o: ../../include/sock_addr.h
-tls_proxy_client_scan.o: ../../include/sys_defs.h
-tls_proxy_client_scan.o: ../../include/vbuf.h
-tls_proxy_client_scan.o: ../../include/vstream.h
-tls_proxy_client_scan.o: ../../include/vstring.h
-tls_proxy_client_scan.o: tls.h
-tls_proxy_client_scan.o: tls_proxy.h
-tls_proxy_client_scan.o: tls_proxy_client_scan.c
-tls_proxy_client_scan.o: tlsrpt_wrapper.h
+tls_proxy_client_init_proto.o: ../../include/argv.h
+tls_proxy_client_init_proto.o: ../../include/argv_attr.h
+tls_proxy_client_init_proto.o: ../../include/attr.h
+tls_proxy_client_init_proto.o: ../../include/check_arg.h
+tls_proxy_client_init_proto.o: ../../include/dns.h
+tls_proxy_client_init_proto.o: ../../include/htable.h
+tls_proxy_client_init_proto.o: ../../include/mail_params.h
+tls_proxy_client_init_proto.o: ../../include/msg.h
+tls_proxy_client_init_proto.o: ../../include/myaddrinfo.h
+tls_proxy_client_init_proto.o: ../../include/mymalloc.h
+tls_proxy_client_init_proto.o: ../../include/name_code.h
+tls_proxy_client_init_proto.o: ../../include/name_mask.h
+tls_proxy_client_init_proto.o: ../../include/nvtable.h
+tls_proxy_client_init_proto.o: ../../include/sock_addr.h
+tls_proxy_client_init_proto.o: ../../include/sys_defs.h
+tls_proxy_client_init_proto.o: ../../include/vbuf.h
+tls_proxy_client_init_proto.o: ../../include/vstream.h
+tls_proxy_client_init_proto.o: ../../include/vstring.h
+tls_proxy_client_init_proto.o: tls.h
+tls_proxy_client_init_proto.o: tls_proxy_attr.h
+tls_proxy_client_init_proto.o: tls_proxy_client_init_proto.c
+tls_proxy_client_init_proto.o: tls_proxy_client_init_proto.h
+tls_proxy_client_init_proto.o: tlsrpt_wrapper.h
+tls_proxy_client_init_proto_test.o: ../../include/argv.h
+tls_proxy_client_init_proto_test.o: ../../include/attr.h
+tls_proxy_client_init_proto_test.o: ../../include/check_arg.h
+tls_proxy_client_init_proto_test.o: ../../include/dns.h
+tls_proxy_client_init_proto_test.o: ../../include/htable.h
+tls_proxy_client_init_proto_test.o: ../../include/mail_params.h
+tls_proxy_client_init_proto_test.o: ../../include/make_attr.h
+tls_proxy_client_init_proto_test.o: ../../include/match_attr.h
+tls_proxy_client_init_proto_test.o: ../../include/msg.h
+tls_proxy_client_init_proto_test.o: ../../include/msg_jmp.h
+tls_proxy_client_init_proto_test.o: ../../include/msg_output.h
+tls_proxy_client_init_proto_test.o: ../../include/msg_vstream.h
+tls_proxy_client_init_proto_test.o: ../../include/myaddrinfo.h
+tls_proxy_client_init_proto_test.o: ../../include/mymalloc.h
+tls_proxy_client_init_proto_test.o: ../../include/myrand.h
+tls_proxy_client_init_proto_test.o: ../../include/name_code.h
+tls_proxy_client_init_proto_test.o: ../../include/name_mask.h
+tls_proxy_client_init_proto_test.o: ../../include/nvtable.h
+tls_proxy_client_init_proto_test.o: ../../include/pmock_expect.h
+tls_proxy_client_init_proto_test.o: ../../include/ptest.h
+tls_proxy_client_init_proto_test.o: ../../include/ptest_main.h
+tls_proxy_client_init_proto_test.o: ../../include/sock_addr.h
+tls_proxy_client_init_proto_test.o: ../../include/stringops.h
+tls_proxy_client_init_proto_test.o: ../../include/sys_defs.h
+tls_proxy_client_init_proto_test.o: ../../include/vbuf.h
+tls_proxy_client_init_proto_test.o: ../../include/vstream.h
+tls_proxy_client_init_proto_test.o: ../../include/vstring.h
+tls_proxy_client_init_proto_test.o: tls.h
+tls_proxy_client_init_proto_test.o: tls_proxy_attr.h
+tls_proxy_client_init_proto_test.o: tls_proxy_client_init_proto.h
+tls_proxy_client_init_proto_test.o: tls_proxy_client_init_proto_test.c
+tls_proxy_client_param_proto.o: ../../include/argv.h
+tls_proxy_client_param_proto.o: ../../include/attr.h
+tls_proxy_client_param_proto.o: ../../include/check_arg.h
+tls_proxy_client_param_proto.o: ../../include/dns.h
+tls_proxy_client_param_proto.o: ../../include/htable.h
+tls_proxy_client_param_proto.o: ../../include/mail_params.h
+tls_proxy_client_param_proto.o: ../../include/msg.h
+tls_proxy_client_param_proto.o: ../../include/myaddrinfo.h
+tls_proxy_client_param_proto.o: ../../include/mymalloc.h
+tls_proxy_client_param_proto.o: ../../include/name_code.h
+tls_proxy_client_param_proto.o: ../../include/name_mask.h
+tls_proxy_client_param_proto.o: ../../include/nvtable.h
+tls_proxy_client_param_proto.o: ../../include/sock_addr.h
+tls_proxy_client_param_proto.o: ../../include/sys_defs.h
+tls_proxy_client_param_proto.o: ../../include/vbuf.h
+tls_proxy_client_param_proto.o: ../../include/vstream.h
+tls_proxy_client_param_proto.o: ../../include/vstring.h
+tls_proxy_client_param_proto.o: tls.h
+tls_proxy_client_param_proto.o: tls_proxy_attr.h
+tls_proxy_client_param_proto.o: tls_proxy_client_param_proto.c
+tls_proxy_client_param_proto.o: tls_proxy_client_param_proto.h
+tls_proxy_client_param_proto_test.o: ../../include/argv.h
+tls_proxy_client_param_proto_test.o: ../../include/attr.h
+tls_proxy_client_param_proto_test.o: ../../include/check_arg.h
+tls_proxy_client_param_proto_test.o: ../../include/dns.h
+tls_proxy_client_param_proto_test.o: ../../include/htable.h
+tls_proxy_client_param_proto_test.o: ../../include/mail_params.h
+tls_proxy_client_param_proto_test.o: ../../include/make_attr.h
+tls_proxy_client_param_proto_test.o: ../../include/match_attr.h
+tls_proxy_client_param_proto_test.o: ../../include/msg.h
+tls_proxy_client_param_proto_test.o: ../../include/msg_jmp.h
+tls_proxy_client_param_proto_test.o: ../../include/msg_output.h
+tls_proxy_client_param_proto_test.o: ../../include/msg_vstream.h
+tls_proxy_client_param_proto_test.o: ../../include/myaddrinfo.h
+tls_proxy_client_param_proto_test.o: ../../include/mymalloc.h
+tls_proxy_client_param_proto_test.o: ../../include/myrand.h
+tls_proxy_client_param_proto_test.o: ../../include/name_code.h
+tls_proxy_client_param_proto_test.o: ../../include/name_mask.h
+tls_proxy_client_param_proto_test.o: ../../include/nvtable.h
+tls_proxy_client_param_proto_test.o: ../../include/pmock_expect.h
+tls_proxy_client_param_proto_test.o: ../../include/ptest.h
+tls_proxy_client_param_proto_test.o: ../../include/ptest_main.h
+tls_proxy_client_param_proto_test.o: ../../include/sock_addr.h
+tls_proxy_client_param_proto_test.o: ../../include/stringops.h
+tls_proxy_client_param_proto_test.o: ../../include/sys_defs.h
+tls_proxy_client_param_proto_test.o: ../../include/vbuf.h
+tls_proxy_client_param_proto_test.o: ../../include/vstream.h
+tls_proxy_client_param_proto_test.o: ../../include/vstring.h
+tls_proxy_client_param_proto_test.o: tls.h
+tls_proxy_client_param_proto_test.o: tls_proxy_attr.h
+tls_proxy_client_param_proto_test.o: tls_proxy_client_param_proto.h
+tls_proxy_client_param_proto_test.o: tls_proxy_client_param_proto_test.c
+tls_proxy_client_start_proto.o: ../../include/argv.h
+tls_proxy_client_start_proto.o: ../../include/argv_attr.h
+tls_proxy_client_start_proto.o: ../../include/attr.h
+tls_proxy_client_start_proto.o: ../../include/check_arg.h
+tls_proxy_client_start_proto.o: ../../include/dns.h
+tls_proxy_client_start_proto.o: ../../include/htable.h
+tls_proxy_client_start_proto.o: ../../include/mail_params.h
+tls_proxy_client_start_proto.o: ../../include/msg.h
+tls_proxy_client_start_proto.o: ../../include/myaddrinfo.h
+tls_proxy_client_start_proto.o: ../../include/mymalloc.h
+tls_proxy_client_start_proto.o: ../../include/name_code.h
+tls_proxy_client_start_proto.o: ../../include/name_mask.h
+tls_proxy_client_start_proto.o: ../../include/nvtable.h
+tls_proxy_client_start_proto.o: ../../include/sock_addr.h
+tls_proxy_client_start_proto.o: ../../include/sys_defs.h
+tls_proxy_client_start_proto.o: ../../include/vbuf.h
+tls_proxy_client_start_proto.o: ../../include/vstream.h
+tls_proxy_client_start_proto.o: ../../include/vstring.h
+tls_proxy_client_start_proto.o: tls.h
+tls_proxy_client_start_proto.o: tls_proxy_attr.h
+tls_proxy_client_start_proto.o: tls_proxy_client_start_proto.c
+tls_proxy_client_start_proto.o: tls_proxy_client_start_proto.h
+tls_proxy_client_start_proto.o: tlsrpt_wrapper.h
 tls_proxy_clnt.o: ../../include/argv.h
 tls_proxy_clnt.o: ../../include/attr.h
 tls_proxy_clnt.o: ../../include/check_arg.h
@@ -416,7 +530,14 @@ tls_proxy_clnt.o: ../../include/vstream.h
 tls_proxy_clnt.o: ../../include/vstring.h
 tls_proxy_clnt.o: tls.h
 tls_proxy_clnt.o: tls_proxy.h
+tls_proxy_clnt.o: tls_proxy_attr.h
+tls_proxy_clnt.o: tls_proxy_client_init_proto.h
+tls_proxy_clnt.o: tls_proxy_client_param_proto.h
+tls_proxy_clnt.o: tls_proxy_client_start_proto.h
 tls_proxy_clnt.o: tls_proxy_clnt.c
+tls_proxy_clnt.o: tls_proxy_server_init_proto.h
+tls_proxy_clnt.o: tls_proxy_server_param_proto.h
+tls_proxy_clnt.o: tls_proxy_server_start_proto.h
 tls_proxy_context_print.o: ../../include/argv.h
 tls_proxy_context_print.o: ../../include/attr.h
 tls_proxy_context_print.o: ../../include/check_arg.h
@@ -434,7 +555,14 @@ tls_proxy_context_print.o: ../../include/vstream.h
 tls_proxy_context_print.o: ../../include/vstring.h
 tls_proxy_context_print.o: tls.h
 tls_proxy_context_print.o: tls_proxy.h
+tls_proxy_context_print.o: tls_proxy_attr.h
+tls_proxy_context_print.o: tls_proxy_client_init_proto.h
+tls_proxy_context_print.o: tls_proxy_client_param_proto.h
+tls_proxy_context_print.o: tls_proxy_client_start_proto.h
 tls_proxy_context_print.o: tls_proxy_context_print.c
+tls_proxy_context_print.o: tls_proxy_server_init_proto.h
+tls_proxy_context_print.o: tls_proxy_server_param_proto.h
+tls_proxy_context_print.o: tls_proxy_server_start_proto.h
 tls_proxy_context_scan.o: ../../include/argv.h
 tls_proxy_context_scan.o: ../../include/attr.h
 tls_proxy_context_scan.o: ../../include/check_arg.h
@@ -453,43 +581,140 @@ tls_proxy_context_scan.o: ../../include/vstream.h
 tls_proxy_context_scan.o: ../../include/vstring.h
 tls_proxy_context_scan.o: tls.h
 tls_proxy_context_scan.o: tls_proxy.h
+tls_proxy_context_scan.o: tls_proxy_attr.h
+tls_proxy_context_scan.o: tls_proxy_client_init_proto.h
+tls_proxy_context_scan.o: tls_proxy_client_param_proto.h
+tls_proxy_context_scan.o: tls_proxy_client_start_proto.h
 tls_proxy_context_scan.o: tls_proxy_context_scan.c
-tls_proxy_server_print.o: ../../include/argv.h
-tls_proxy_server_print.o: ../../include/attr.h
-tls_proxy_server_print.o: ../../include/check_arg.h
-tls_proxy_server_print.o: ../../include/dns.h
-tls_proxy_server_print.o: ../../include/htable.h
-tls_proxy_server_print.o: ../../include/myaddrinfo.h
-tls_proxy_server_print.o: ../../include/mymalloc.h
-tls_proxy_server_print.o: ../../include/name_code.h
-tls_proxy_server_print.o: ../../include/name_mask.h
-tls_proxy_server_print.o: ../../include/nvtable.h
-tls_proxy_server_print.o: ../../include/sock_addr.h
-tls_proxy_server_print.o: ../../include/sys_defs.h
-tls_proxy_server_print.o: ../../include/vbuf.h
-tls_proxy_server_print.o: ../../include/vstream.h
-tls_proxy_server_print.o: ../../include/vstring.h
-tls_proxy_server_print.o: tls.h
-tls_proxy_server_print.o: tls_proxy.h
-tls_proxy_server_print.o: tls_proxy_server_print.c
-tls_proxy_server_scan.o: ../../include/argv.h
-tls_proxy_server_scan.o: ../../include/attr.h
-tls_proxy_server_scan.o: ../../include/check_arg.h
-tls_proxy_server_scan.o: ../../include/dns.h
-tls_proxy_server_scan.o: ../../include/htable.h
-tls_proxy_server_scan.o: ../../include/myaddrinfo.h
-tls_proxy_server_scan.o: ../../include/mymalloc.h
-tls_proxy_server_scan.o: ../../include/name_code.h
-tls_proxy_server_scan.o: ../../include/name_mask.h
-tls_proxy_server_scan.o: ../../include/nvtable.h
-tls_proxy_server_scan.o: ../../include/sock_addr.h
-tls_proxy_server_scan.o: ../../include/sys_defs.h
-tls_proxy_server_scan.o: ../../include/vbuf.h
-tls_proxy_server_scan.o: ../../include/vstream.h
-tls_proxy_server_scan.o: ../../include/vstring.h
-tls_proxy_server_scan.o: tls.h
-tls_proxy_server_scan.o: tls_proxy.h
-tls_proxy_server_scan.o: tls_proxy_server_scan.c
+tls_proxy_context_scan.o: tls_proxy_server_init_proto.h
+tls_proxy_context_scan.o: tls_proxy_server_param_proto.h
+tls_proxy_context_scan.o: tls_proxy_server_start_proto.h
+tls_proxy_server_init_proto.o: ../../include/argv.h
+tls_proxy_server_init_proto.o: ../../include/attr.h
+tls_proxy_server_init_proto.o: ../../include/check_arg.h
+tls_proxy_server_init_proto.o: ../../include/dns.h
+tls_proxy_server_init_proto.o: ../../include/htable.h
+tls_proxy_server_init_proto.o: ../../include/mail_params.h
+tls_proxy_server_init_proto.o: ../../include/msg.h
+tls_proxy_server_init_proto.o: ../../include/myaddrinfo.h
+tls_proxy_server_init_proto.o: ../../include/mymalloc.h
+tls_proxy_server_init_proto.o: ../../include/name_code.h
+tls_proxy_server_init_proto.o: ../../include/name_mask.h
+tls_proxy_server_init_proto.o: ../../include/nvtable.h
+tls_proxy_server_init_proto.o: ../../include/sock_addr.h
+tls_proxy_server_init_proto.o: ../../include/sys_defs.h
+tls_proxy_server_init_proto.o: ../../include/vbuf.h
+tls_proxy_server_init_proto.o: ../../include/vstream.h
+tls_proxy_server_init_proto.o: ../../include/vstring.h
+tls_proxy_server_init_proto.o: tls.h
+tls_proxy_server_init_proto.o: tls_proxy_attr.h
+tls_proxy_server_init_proto.o: tls_proxy_server_init_proto.c
+tls_proxy_server_init_proto.o: tls_proxy_server_init_proto.h
+tls_proxy_server_init_proto_test.o: ../../include/argv.h
+tls_proxy_server_init_proto_test.o: ../../include/attr.h
+tls_proxy_server_init_proto_test.o: ../../include/check_arg.h
+tls_proxy_server_init_proto_test.o: ../../include/dns.h
+tls_proxy_server_init_proto_test.o: ../../include/htable.h
+tls_proxy_server_init_proto_test.o: ../../include/mail_params.h
+tls_proxy_server_init_proto_test.o: ../../include/make_attr.h
+tls_proxy_server_init_proto_test.o: ../../include/match_attr.h
+tls_proxy_server_init_proto_test.o: ../../include/msg.h
+tls_proxy_server_init_proto_test.o: ../../include/msg_jmp.h
+tls_proxy_server_init_proto_test.o: ../../include/msg_output.h
+tls_proxy_server_init_proto_test.o: ../../include/msg_vstream.h
+tls_proxy_server_init_proto_test.o: ../../include/myaddrinfo.h
+tls_proxy_server_init_proto_test.o: ../../include/mymalloc.h
+tls_proxy_server_init_proto_test.o: ../../include/myrand.h
+tls_proxy_server_init_proto_test.o: ../../include/name_code.h
+tls_proxy_server_init_proto_test.o: ../../include/name_mask.h
+tls_proxy_server_init_proto_test.o: ../../include/nvtable.h
+tls_proxy_server_init_proto_test.o: ../../include/pmock_expect.h
+tls_proxy_server_init_proto_test.o: ../../include/ptest.h
+tls_proxy_server_init_proto_test.o: ../../include/ptest_main.h
+tls_proxy_server_init_proto_test.o: ../../include/sock_addr.h
+tls_proxy_server_init_proto_test.o: ../../include/stringops.h
+tls_proxy_server_init_proto_test.o: ../../include/sys_defs.h
+tls_proxy_server_init_proto_test.o: ../../include/vbuf.h
+tls_proxy_server_init_proto_test.o: ../../include/vstream.h
+tls_proxy_server_init_proto_test.o: ../../include/vstring.h
+tls_proxy_server_init_proto_test.o: tls.h
+tls_proxy_server_init_proto_test.o: tls_proxy_attr.h
+tls_proxy_server_init_proto_test.o: tls_proxy_server_init_proto.h
+tls_proxy_server_init_proto_test.o: tls_proxy_server_init_proto_test.c
+tls_proxy_server_param_proto.o: ../../include/argv.h
+tls_proxy_server_param_proto.o: ../../include/attr.h
+tls_proxy_server_param_proto.o: ../../include/check_arg.h
+tls_proxy_server_param_proto.o: ../../include/dns.h
+tls_proxy_server_param_proto.o: ../../include/htable.h
+tls_proxy_server_param_proto.o: ../../include/mail_params.h
+tls_proxy_server_param_proto.o: ../../include/msg.h
+tls_proxy_server_param_proto.o: ../../include/myaddrinfo.h
+tls_proxy_server_param_proto.o: ../../include/mymalloc.h
+tls_proxy_server_param_proto.o: ../../include/name_code.h
+tls_proxy_server_param_proto.o: ../../include/name_mask.h
+tls_proxy_server_param_proto.o: ../../include/nvtable.h
+tls_proxy_server_param_proto.o: ../../include/sock_addr.h
+tls_proxy_server_param_proto.o: ../../include/sys_defs.h
+tls_proxy_server_param_proto.o: ../../include/vbuf.h
+tls_proxy_server_param_proto.o: ../../include/vstream.h
+tls_proxy_server_param_proto.o: ../../include/vstring.h
+tls_proxy_server_param_proto.o: tls.h
+tls_proxy_server_param_proto.o: tls_proxy_attr.h
+tls_proxy_server_param_proto.o: tls_proxy_server_param_proto.c
+tls_proxy_server_param_proto.o: tls_proxy_server_param_proto.h
+tls_proxy_server_param_proto_test.o: ../../include/argv.h
+tls_proxy_server_param_proto_test.o: ../../include/attr.h
+tls_proxy_server_param_proto_test.o: ../../include/check_arg.h
+tls_proxy_server_param_proto_test.o: ../../include/dns.h
+tls_proxy_server_param_proto_test.o: ../../include/htable.h
+tls_proxy_server_param_proto_test.o: ../../include/mail_params.h
+tls_proxy_server_param_proto_test.o: ../../include/make_attr.h
+tls_proxy_server_param_proto_test.o: ../../include/match_attr.h
+tls_proxy_server_param_proto_test.o: ../../include/msg.h
+tls_proxy_server_param_proto_test.o: ../../include/msg_jmp.h
+tls_proxy_server_param_proto_test.o: ../../include/msg_output.h
+tls_proxy_server_param_proto_test.o: ../../include/msg_vstream.h
+tls_proxy_server_param_proto_test.o: ../../include/myaddrinfo.h
+tls_proxy_server_param_proto_test.o: ../../include/mymalloc.h
+tls_proxy_server_param_proto_test.o: ../../include/myrand.h
+tls_proxy_server_param_proto_test.o: ../../include/name_code.h
+tls_proxy_server_param_proto_test.o: ../../include/name_mask.h
+tls_proxy_server_param_proto_test.o: ../../include/nvtable.h
+tls_proxy_server_param_proto_test.o: ../../include/pmock_expect.h
+tls_proxy_server_param_proto_test.o: ../../include/ptest.h
+tls_proxy_server_param_proto_test.o: ../../include/ptest_main.h
+tls_proxy_server_param_proto_test.o: ../../include/sock_addr.h
+tls_proxy_server_param_proto_test.o: ../../include/stringops.h
+tls_proxy_server_param_proto_test.o: ../../include/sys_defs.h
+tls_proxy_server_param_proto_test.o: ../../include/vbuf.h
+tls_proxy_server_param_proto_test.o: ../../include/vstream.h
+tls_proxy_server_param_proto_test.o: ../../include/vstring.h
+tls_proxy_server_param_proto_test.o: tls.h
+tls_proxy_server_param_proto_test.o: tls_proxy_attr.h
+tls_proxy_server_param_proto_test.o: tls_proxy_server_param_proto.h
+tls_proxy_server_param_proto_test.o: tls_proxy_server_param_proto_test.c
+tls_proxy_server_start_proto.o: ../../include/argv.h
+tls_proxy_server_start_proto.o: ../../include/argv_attr.h
+tls_proxy_server_start_proto.o: ../../include/attr.h
+tls_proxy_server_start_proto.o: ../../include/check_arg.h
+tls_proxy_server_start_proto.o: ../../include/dns.h
+tls_proxy_server_start_proto.o: ../../include/htable.h
+tls_proxy_server_start_proto.o: ../../include/mail_params.h
+tls_proxy_server_start_proto.o: ../../include/msg.h
+tls_proxy_server_start_proto.o: ../../include/myaddrinfo.h
+tls_proxy_server_start_proto.o: ../../include/mymalloc.h
+tls_proxy_server_start_proto.o: ../../include/name_code.h
+tls_proxy_server_start_proto.o: ../../include/name_mask.h
+tls_proxy_server_start_proto.o: ../../include/nvtable.h
+tls_proxy_server_start_proto.o: ../../include/sock_addr.h
+tls_proxy_server_start_proto.o: ../../include/sys_defs.h
+tls_proxy_server_start_proto.o: ../../include/vbuf.h
+tls_proxy_server_start_proto.o: ../../include/vstream.h
+tls_proxy_server_start_proto.o: ../../include/vstring.h
+tls_proxy_server_start_proto.o: tls.h
+tls_proxy_server_start_proto.o: tls_proxy_attr.h
+tls_proxy_server_start_proto.o: tls_proxy_server_start_proto.c
+tls_proxy_server_start_proto.o: tls_proxy_server_start_proto.h
 tls_scache.o: ../../include/argv.h
 tls_scache.o: ../../include/check_arg.h
 tls_scache.o: ../../include/dict.h
index d5cbdb4d1511fa8f5abc497378cb075a8d1b36d2..e52d5260c77f51eaffe9667d6f54cead67f4a671 100644 (file)
@@ -3,11 +3,11 @@
 
 /*++
 /* NAME
-/*     tls_proxy_clnt 3h
+/*     tls_proxy 3h
 /* SUMMARY
 /*     postscreen TLS proxy support
 /* SYNOPSIS
-/*     #include <tls_proxy_clnt.h>
+/*     #include <tls_proxy.h>
 /* DESCRIPTION
 /* .nf
 
 #define TLS_PROXY_FLAG_ROLE_CLIENT     (1<<1)  /* request client role */
 #define TLS_PROXY_FLAG_SEND_CONTEXT    (1<<2)  /* send TLS context */
 
-#ifdef USE_TLS
+#include <tls_proxy_attr.h>
 
- /*
-  * TLS_CLIENT_PARAMS structure, to communicate global TLS library settings
-  * that are the same for all TLS client contexts. This information is used
-  * in tlsproxy(8) to detect inconsistencies. If this structure is changed,
-  * update all TLS_CLIENT_PARAMS related functions in tls_proxy_client_*.c.
-  * 
-  * In the serialization these attributes are identified by their configuration
-  * parameter names.
-  * 
-  * NOTE: this does not include openssl_path.
-  * 
-  * TODO: TLS_SERVER_PARAM structure, like TLS_CLIENT_PARAMS plus
-  * VAR_TLS_SERVER_SNI_MAPS.
-  */
-typedef struct TLS_CLIENT_PARAMS {
-    char   *tls_cnf_file;
-    char   *tls_cnf_name;
-    char   *tls_high_clist;
-    char   *tls_medium_clist;
-    char   *tls_null_clist;
-    char   *tls_eecdh_auto;
-    char   *tls_eecdh_strong;
-    char   *tls_eecdh_ultra;
-    char   *tls_ffdhe_auto;
-    char   *tls_bug_tweaks;
-    char   *tls_ssl_options;
-    char   *tls_dane_digests;
-    char   *tls_mgr_service;
-    char   *tls_tkt_cipher;
-    int     tls_daemon_rand_bytes;
-    int     tls_append_def_CA;
-    int     tls_preempt_clist;
-    int     tls_multi_wildcard;
-} TLS_CLIENT_PARAMS;
+#include <tls_proxy_client_param_proto.h>
+#include <tls_proxy_client_init_proto.h>
+#include <tls_proxy_client_start_proto.h>
 
-#define TLS_PROXY_PARAMS(params, a1, a2, a3, a4, a5, a6, a7, a8, \
-    a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) \
-    (((params)->a1), ((params)->a2), ((params)->a3), \
-    ((params)->a4), ((params)->a5), ((params)->a6), ((params)->a7), \
-    ((params)->a8), ((params)->a9), ((params)->a10), ((params)->a11), \
-    ((params)->a12), ((params)->a13), ((params)->a14), ((params)->a15), \
-    ((params)->a16), ((params)->a17), ((params)->a18))
+#include <tls_proxy_server_param_proto.h>
+#include <tls_proxy_server_init_proto.h>
+#include <tls_proxy_server_start_proto.h>
 
- /*
-  * tls_proxy_client_param_misc.c, tls_proxy_client_param_print.c, and
-  * tls_proxy_client_param_scan.c.
-  */
-extern TLS_CLIENT_PARAMS *tls_proxy_client_param_from_config(TLS_CLIENT_PARAMS *);
-extern char *tls_proxy_client_param_serialize(ATTR_PRINT_COMMON_FN, VSTRING *, const TLS_CLIENT_PARAMS *);
-extern int tls_proxy_client_param_print(ATTR_PRINT_COMMON_FN, VSTREAM *, int, const void *);
-extern void tls_proxy_client_param_free(TLS_CLIENT_PARAMS *);
-extern int tls_proxy_client_param_scan(ATTR_SCAN_COMMON_FN, VSTREAM *, int, void *);
+#ifdef USE_TLS
 
  /*
   * Functions that handle TLS_XXX_INIT_PROPS and TLS_XXX_START_PROPS. These
@@ -99,181 +56,13 @@ extern VSTREAM *tls_proxy_open(const char *, int, VSTREAM *, const char *,
                                       const char *, int, int, const char *,
                                       void *, void *, void *);
 
-#define TLS_PROXY_CLIENT_INIT_PROPS(props, a1, a2, a3, a4, a5, a6, a7, a8, \
-    a9, a10, a11, a12, a13, a14) \
-    (((props)->a1), ((props)->a2), ((props)->a3), \
-    ((props)->a4), ((props)->a5), ((props)->a6), ((props)->a7), \
-    ((props)->a8), ((props)->a9), ((props)->a10), ((props)->a11), \
-    ((props)->a12), ((props)->a13), ((props)->a14))
-
-#define TLS_PROXY_CLIENT_START_PROPS(props, a1, a2, a3, a4, a5, a6, a7, a8, \
-    a9, a10, a11, a12, a13, a14, a15, a16, a17) \
-    (((props)->a1), ((props)->a2), ((props)->a3), \
-    ((props)->a4), ((props)->a5), ((props)->a6), ((props)->a7), \
-    ((props)->a8), ((props)->a9), ((props)->a10), ((props)->a11), \
-    ((props)->a12), ((props)->a13), ((props)->a14), ((props)->a15), \
-    ((props)->a16), ((props)->a17))
-
 extern TLS_SESS_STATE *tls_proxy_context_receive(VSTREAM *);
 extern void tls_proxy_context_free(TLS_SESS_STATE *);
 extern int tls_proxy_context_print(ATTR_PRINT_COMMON_FN, VSTREAM *, int, const void *);
 extern int tls_proxy_context_scan(ATTR_SCAN_COMMON_FN, VSTREAM *, int, void *);
 
-extern int tls_proxy_client_init_print(ATTR_PRINT_COMMON_FN, VSTREAM *, int, const void *);
-extern int tls_proxy_client_init_scan(ATTR_SCAN_COMMON_FN, VSTREAM *, int, void *);
-extern void tls_proxy_client_init_free(TLS_CLIENT_INIT_PROPS *);
-extern char *tls_proxy_client_init_serialize(ATTR_PRINT_COMMON_FN, VSTRING *, const TLS_CLIENT_INIT_PROPS *);
-
-extern int tls_proxy_client_start_print(ATTR_PRINT_COMMON_FN, VSTREAM *, int, const void *);
-extern int tls_proxy_client_start_scan(ATTR_SCAN_COMMON_FN, VSTREAM *, int, void *);
-extern void tls_proxy_client_start_free(TLS_CLIENT_START_PROPS *);
-
-extern int tls_proxy_server_init_print(ATTR_PRINT_COMMON_FN, VSTREAM *, int, const void *);
-extern int tls_proxy_server_init_scan(ATTR_SCAN_COMMON_FN, VSTREAM *, int, void *);
-extern void tls_proxy_server_init_free(TLS_SERVER_INIT_PROPS *);
-
-extern int tls_proxy_server_start_print(ATTR_PRINT_COMMON_FN, VSTREAM *, int, const void *);
-extern int tls_proxy_server_start_scan(ATTR_SCAN_COMMON_FN, VSTREAM *, int, void *);
-
-extern void tls_proxy_server_start_free(TLS_SERVER_START_PROPS *);
-
 #endif                                 /* USE_TLS */
 
- /*
-  * TLSPROXY attributes, unconditionally exposed.
-  */
-#define TLS_ATTR_REMOTE_ENDPT  "remote_endpoint"       /* name[addr]:port */
-#define TLS_ATTR_FLAGS         "flags"
-#define TLS_ATTR_TIMEOUT       "timeout"
-#define TLS_ATTR_SERVERID      "serverid"
-
-#ifdef USE_TLS
-
- /*
-  * Misc attributes.
-  */
-#define TLS_ATTR_COUNT         "count"
-
- /*
-  * TLS_SESS_STATE attributes.
-  */
-#define TLS_ATTR_PEER_CN       "peer_CN"
-#define TLS_ATTR_ISSUER_CN     "issuer_CN"
-#define TLS_ATTR_PEER_CERT_FPT "peer_fingerprint"
-#define TLS_ATTR_PEER_PKEY_FPT "peer_pubkey_fingerprint"
-#define TLS_ATTR_SEC_LEVEL      "level"
-#define TLS_ATTR_PEER_STATUS   "peer_status"
-#define TLS_ATTR_CIPHER_PROTOCOL "cipher_protocol"
-#define TLS_ATTR_CIPHER_NAME   "cipher_name"
-#define TLS_ATTR_CIPHER_USEBITS        "cipher_usebits"
-#define TLS_ATTR_CIPHER_ALGBITS        "cipher_algbits"
-#define TLS_ATTR_KEX_NAME      "key_exchange"
-#define TLS_ATTR_KEX_CURVE     "key_exchange_curve"
-#define TLS_ATTR_KEX_BITS      "key_exchange_bits"
-#define TLS_ATTR_CTOS_RPK      "ctos_rpk"
-#define TLS_ATTR_STOC_RPK      "stoc_rpk"
-#define TLS_ATTR_CLNT_SIG_NAME "clnt_signature"
-#define TLS_ATTR_CLNT_SIG_CURVE        "clnt_signature_curve"
-#define TLS_ATTR_CLNT_SIG_BITS "clnt_signature_bits"
-#define TLS_ATTR_CLNT_SIG_DGST "clnt_signature_digest"
-#define TLS_ATTR_SRVR_SIG_NAME "srvr_signature"
-#define TLS_ATTR_SRVR_SIG_CURVE        "srvr_signature_curve"
-#define TLS_ATTR_SRVR_SIG_BITS "srvr_signature_bits"
-#define TLS_ATTR_SRVR_SIG_DGST "srvr_signature_digest"
-#define TLS_ATTR_NAMADDR       "namaddr"
-#define TLS_ATTR_RPT_REPORTED  "rpt_reported"
-
- /*
-  * TLS_SERVER_INIT_PROPS attributes.
-  */
-#define TLS_ATTR_LOG_PARAM     "log_param"
-#define TLS_ATTR_LOG_LEVEL     "log_level"
-#define TLS_ATTR_VERIFYDEPTH   "verifydepth"
-#define TLS_ATTR_CACHE_TYPE    "cache_type"
-#define TLS_ATTR_SET_SESSID    "set_sessid"
-#define TLS_ATTR_CHAIN_FILES   "chain_files"
-#define TLS_ATTR_CERT_FILE     "cert_file"
-#define TLS_ATTR_KEY_FILE      "key_file"
-#define TLS_ATTR_DCERT_FILE    "dcert_file"
-#define TLS_ATTR_DKEY_FILE     "dkey_file"
-#define TLS_ATTR_ECCERT_FILE   "eccert_file"
-#define TLS_ATTR_ECKEY_FILE    "eckey_file"
-#define TLS_ATTR_CAFILE                "CAfile"
-#define TLS_ATTR_CAPATH                "CApath"
-#define TLS_ATTR_PROTOCOLS     "protocols"
-#define TLS_ATTR_EECDH_GRADE   "eecdh_grade"
-#define TLS_ATTR_DH1K_PARAM_FILE "dh1024_param_file"
-#define TLS_ATTR_DH512_PARAM_FILE "dh512_param_file"
-#define TLS_ATTR_ASK_CCERT     "ask_ccert"
-#define TLS_ATTR_MDALG         "mdalg"
-
- /*
-  * TLS_SERVER_START_PROPS attributes.
-  */
-#define TLS_ATTR_TIMEOUT       "timeout"
-#define TLS_ATTR_REQUIRECERT   "requirecert"
-#define TLS_ATTR_SERVERID      "serverid"
-#define TLS_ATTR_NAMADDR       "namaddr"
-#define TLS_ATTR_CIPHER_GRADE  "cipher_grade"
-#define TLS_ATTR_CIPHER_EXCLUSIONS "cipher_exclusions"
-#define TLS_ATTR_MDALG         "mdalg"
-
- /*
-  * TLS_CLIENT_INIT_PROPS attributes.
-  */
-#define TLS_ATTR_CNF_FILE      "config_file"
-#define TLS_ATTR_CNF_NAME      "config_name"
-#define TLS_ATTR_LOG_PARAM     "log_param"
-#define TLS_ATTR_LOG_LEVEL     "log_level"
-#define TLS_ATTR_VERIFYDEPTH   "verifydepth"
-#define TLS_ATTR_CACHE_TYPE    "cache_type"
-#define TLS_ATTR_CHAIN_FILES   "chain_files"
-#define TLS_ATTR_CERT_FILE     "cert_file"
-#define TLS_ATTR_KEY_FILE      "key_file"
-#define TLS_ATTR_DCERT_FILE    "dcert_file"
-#define TLS_ATTR_DKEY_FILE     "dkey_file"
-#define TLS_ATTR_ECCERT_FILE   "eccert_file"
-#define TLS_ATTR_ECKEY_FILE    "eckey_file"
-#define TLS_ATTR_CAFILE                "CAfile"
-#define TLS_ATTR_CAPATH                "CApath"
-#define TLS_ATTR_MDALG         "mdalg"
-
- /*
-  * TLS_CLIENT_START_PROPS attributes.
-  */
-#define TLS_ATTR_TIMEOUT       "timeout"
-#define TLS_ATTR_ENABLE_RPK    "enable_rpk"
-#define TLS_ATTR_TLS_LEVEL     "tls_level"
-#define TLS_ATTR_NEXTHOP       "nexthop"
-#define TLS_ATTR_HOST          "host"
-#define TLS_ATTR_NAMADDR       "namaddr"
-#define TLS_ATTR_SNI           "sni"
-#define TLS_ATTR_SERVERID      "serverid"
-#define TLS_ATTR_HELO          "helo"
-#define TLS_ATTR_PROTOCOLS     "protocols"
-#define TLS_ATTR_CIPHER_GRADE  "cipher_grade"
-#define TLS_ATTR_CIPHER_EXCLUSIONS "cipher_exclusions"
-#define TLS_ATTR_MATCHARGV     "matchargv"
-#define TLS_ATTR_MDALG         "mdalg"
-#define TLS_ATTR_DANE          "dane"
-#define TLS_ATTR_TLSRPT                "tlsrpt"
-#define TLS_ATTR_FFAIL_TYPE    "forced_failure_type"
-
- /*
-  * TLS_TLSA attributes.
-  */
-#define TLS_ATTR_USAGE         "usage"
-#define TLS_ATTR_SELECTOR      "selector"
-#define TLS_ATTR_MTYPE         "mtype"
-#define TLS_ATTR_DATA          "data"
-
- /*
-  * TLS_DANE attributes.
-  */
-#define TLS_ATTR_DOMAIN                "domain"
-
-#endif
-
 /* LICENSE
 /* .ad
 /* .fi
@@ -288,6 +77,9 @@ extern void tls_proxy_server_start_free(TLS_SERVER_START_PROPS *);
 /*     Google, Inc.
 /*     111 8th Avenue
 /*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 #endif
diff --git a/postfix/src/tls/tls_proxy_attr.h b/postfix/src/tls/tls_proxy_attr.h
new file mode 100644 (file)
index 0000000..f539de6
--- /dev/null
@@ -0,0 +1,174 @@
+#ifndef _TLS_PROXY_ATTR_H_INCLUDED_
+#define _TLS_PROXY_ATTR_H_INCLUDED_
+
+/*++
+/* NAME
+/*     tls_proxy_attr 3h
+/* SUMMARY
+/*     postscreen TLS proxy support
+/* SYNOPSIS
+/*     #include <tls_proxy_attr.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * TLS library.
+  */
+#include <tls.h>
+
+ /*
+  * TLSPROXY attributes, unconditionally exposed.
+  */
+#define TLS_ATTR_REMOTE_ENDPT  "remote_endpoint"       /* name[addr]:port */
+#define TLS_ATTR_FLAGS         "flags"
+#define TLS_ATTR_TIMEOUT       "timeout"
+#define TLS_ATTR_SERVERID      "serverid"
+
+#ifdef USE_TLS
+
+ /*
+  * Misc attributes.
+  */
+#define TLS_ATTR_COUNT         "count"
+
+ /*
+  * TLS_SESS_STATE attributes.
+  */
+#define TLS_ATTR_PEER_CN       "peer_CN"
+#define TLS_ATTR_ISSUER_CN     "issuer_CN"
+#define TLS_ATTR_PEER_CERT_FPT "peer_fingerprint"
+#define TLS_ATTR_PEER_PKEY_FPT "peer_pubkey_fingerprint"
+#define TLS_ATTR_SEC_LEVEL      "level"
+#define TLS_ATTR_PEER_STATUS   "peer_status"
+#define TLS_ATTR_CIPHER_PROTOCOL "cipher_protocol"
+#define TLS_ATTR_CIPHER_NAME   "cipher_name"
+#define TLS_ATTR_CIPHER_USEBITS        "cipher_usebits"
+#define TLS_ATTR_CIPHER_ALGBITS        "cipher_algbits"
+#define TLS_ATTR_KEX_NAME      "key_exchange"
+#define TLS_ATTR_KEX_CURVE     "key_exchange_curve"
+#define TLS_ATTR_KEX_BITS      "key_exchange_bits"
+#define TLS_ATTR_CTOS_RPK      "ctos_rpk"
+#define TLS_ATTR_STOC_RPK      "stoc_rpk"
+#define TLS_ATTR_CLNT_SIG_NAME "clnt_signature"
+#define TLS_ATTR_CLNT_SIG_CURVE        "clnt_signature_curve"
+#define TLS_ATTR_CLNT_SIG_BITS "clnt_signature_bits"
+#define TLS_ATTR_CLNT_SIG_DGST "clnt_signature_digest"
+#define TLS_ATTR_SRVR_SIG_NAME "srvr_signature"
+#define TLS_ATTR_SRVR_SIG_CURVE        "srvr_signature_curve"
+#define TLS_ATTR_SRVR_SIG_BITS "srvr_signature_bits"
+#define TLS_ATTR_SRVR_SIG_DGST "srvr_signature_digest"
+#define TLS_ATTR_NAMADDR       "namaddr"
+#define TLS_ATTR_RPT_REPORTED  "rpt_reported"
+
+ /*
+  * TLS_SERVER_INIT_PROPS attributes.
+  */
+#define TLS_ATTR_LOG_PARAM     "log_param"
+#define TLS_ATTR_LOG_LEVEL     "log_level"
+#define TLS_ATTR_VERIFYDEPTH   "verifydepth"
+#define TLS_ATTR_CACHE_TYPE    "cache_type"
+#define TLS_ATTR_SET_SESSID    "set_sessid"
+#define TLS_ATTR_CHAIN_FILES   "chain_files"
+#define TLS_ATTR_CERT_FILE     "cert_file"
+#define TLS_ATTR_KEY_FILE      "key_file"
+#define TLS_ATTR_DCERT_FILE    "dcert_file"
+#define TLS_ATTR_DKEY_FILE     "dkey_file"
+#define TLS_ATTR_ECCERT_FILE   "eccert_file"
+#define TLS_ATTR_ECKEY_FILE    "eckey_file"
+#define TLS_ATTR_CAFILE                "CAfile"
+#define TLS_ATTR_CAPATH                "CApath"
+#define TLS_ATTR_PROTOCOLS     "protocols"
+#define TLS_ATTR_EECDH_GRADE   "eecdh_grade"
+#define TLS_ATTR_DH1K_PARAM_FILE "dh1024_param_file"
+#define TLS_ATTR_DH512_PARAM_FILE "dh512_param_file"
+#define TLS_ATTR_ASK_CCERT     "ask_ccert"
+#define TLS_ATTR_MDALG         "mdalg"
+
+ /*
+  * TLS_SERVER_START_PROPS attributes.
+  */
+#define TLS_ATTR_TIMEOUT       "timeout"
+#define TLS_ATTR_ENABLE_RPK    "enable_rpk"
+#define TLS_ATTR_REQUIRECERT   "requirecert"
+#define TLS_ATTR_SERVERID      "serverid"
+#define TLS_ATTR_NAMADDR       "namaddr"
+#define TLS_ATTR_CIPHER_GRADE  "cipher_grade"
+#define TLS_ATTR_CIPHER_EXCLUSIONS "cipher_exclusions"
+#define TLS_ATTR_MDALG         "mdalg"
+
+ /*
+  * TLS_CLIENT_INIT_PROPS attributes.
+  */
+#define TLS_ATTR_CNF_FILE      "config_file"
+#define TLS_ATTR_CNF_NAME      "config_name"
+#define TLS_ATTR_LOG_PARAM     "log_param"
+#define TLS_ATTR_LOG_LEVEL     "log_level"
+#define TLS_ATTR_VERIFYDEPTH   "verifydepth"
+#define TLS_ATTR_CACHE_TYPE    "cache_type"
+#define TLS_ATTR_CHAIN_FILES   "chain_files"
+#define TLS_ATTR_CERT_FILE     "cert_file"
+#define TLS_ATTR_KEY_FILE      "key_file"
+#define TLS_ATTR_DCERT_FILE    "dcert_file"
+#define TLS_ATTR_DKEY_FILE     "dkey_file"
+#define TLS_ATTR_ECCERT_FILE   "eccert_file"
+#define TLS_ATTR_ECKEY_FILE    "eckey_file"
+#define TLS_ATTR_CAFILE                "CAfile"
+#define TLS_ATTR_CAPATH                "CApath"
+#define TLS_ATTR_MDALG         "mdalg"
+
+ /*
+  * TLS_CLIENT_START_PROPS attributes.
+  */
+#define TLS_ATTR_TIMEOUT       "timeout"
+#define TLS_ATTR_ENABLE_RPK    "enable_rpk"
+#define TLS_ATTR_TLS_LEVEL     "tls_level"
+#define TLS_ATTR_NEXTHOP       "nexthop"
+#define TLS_ATTR_HOST          "host"
+#define TLS_ATTR_NAMADDR       "namaddr"
+#define TLS_ATTR_SNI           "sni"
+#define TLS_ATTR_SERVERID      "serverid"
+#define TLS_ATTR_HELO          "helo"
+#define TLS_ATTR_PROTOCOLS     "protocols"
+#define TLS_ATTR_CIPHER_GRADE  "cipher_grade"
+#define TLS_ATTR_CIPHER_EXCLUSIONS "cipher_exclusions"
+#define TLS_ATTR_MATCHARGV     "matchargv"
+#define TLS_ATTR_MDALG         "mdalg"
+#define TLS_ATTR_DANE          "dane"
+#define TLS_ATTR_TLSRPT                "tlsrpt"
+#define TLS_ATTR_FFAIL_TYPE    "forced_failure_type"
+
+ /*
+  * TLS_TLSA attributes.
+  */
+#define TLS_ATTR_USAGE         "usage"
+#define TLS_ATTR_SELECTOR      "selector"
+#define TLS_ATTR_MTYPE         "mtype"
+#define TLS_ATTR_DATA          "data"
+
+ /*
+  * TLS_DANE attributes.
+  */
+#define TLS_ATTR_DOMAIN                "domain"
+
+#endif
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*
+/*     Wietse Venema
+/*     Google, Inc.
+/*     111 8th Avenue
+/*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif
diff --git a/postfix/src/tls/tls_proxy_client_init_proto.c b/postfix/src/tls/tls_proxy_client_init_proto.c
new file mode 100644 (file)
index 0000000..18b293a
--- /dev/null
@@ -0,0 +1,284 @@
+/*++
+/* NAME
+/*     tls_proxy_client_init_proto 3
+/* SUMMARY
+/*     TLS_CLIENT_INIT structure support
+/* SYNOPSIS
+/*     #include <tls_proxy_client_init_proto.h>
+/*
+/*     char    *tls_proxy_client_init_serialize(print_fn, buf, init_props)
+/*     ATTR_PRINT_COMMON_FN print_fn;
+/*     VSTRING *buf;
+/*     const TLS_CLIENT_INIT_PROPS *init_props;
+/*
+/*     TLS_CLIENT_INIT_PROPS *tls_proxy_client_init_from_string(
+/*     ATTR_SCAN_COMMON_FN scan_fn,
+/*     const VSTRING *buf)
+/*
+/*     int     tls_proxy_client_init_print(print_fn, stream, flags, ptr)
+/*     ATTR_PRINT_COMMON_FN print_fn;
+/*     VSTREAM *stream;
+/*     int     flags;
+/*     const void *ptr;
+/*
+/*     int     tls_proxy_client_init_scan(scan_fn, stream, flags, ptr)
+/*     ATTR_SCAN_COMMON_FN scan_fn;
+/*     VSTREAM *stream;
+/*     int     flags;
+/*     void    *ptr;
+/*
+/*     void    tls_proxy_client_init_free(init_props)
+/*     TLS_CLIENT_INIT_PROPS *init_props;
+/* DESCRIPTION
+/*     tls_proxy_client_init_serialize() serializes the specified
+/*     object to a memory buffer, using the specified print function
+/*     (typically, attr_print_plain). The result can be used
+/*     determine whether there are any differences between instances
+/*     of the same object type.
+/*
+/*     tls_proxy_client_init_from_string() deserializes the specified
+/*     buffer into a TLS_CLIENT_INIT_PROPS object, and returns null in case
+/*     of error. The result if not null should be passed to
+/*     tls_proxy_client_init_free().
+/*
+/*      tls_proxy_client_init_print() writes a full TLS_CLIENT_INIT_PROPS
+/*      structure to the named stream using the specified attribute
+/*      print routine. tls_proxy_client_init_print() is meant to
+/*      be passed as a call-back to attr_print(), thusly:
+/*
+/*      SEND_ATTR_FUNC(tls_proxy_client_init_print, (const void *) init_props), ...
+/*
+/*     tls_proxy_client_init_scan() reads a full TLS_CLIENT_INIT_PROPS
+/*     structure from the named stream using the specified attribute
+/*     scan routine. tls_proxy_client_init_scan() is meant to be passed
+/*     as a call-back function to attr_scan(), as shown below.
+/*
+/*     tls_proxy_client_init_free() destroys a TLS_CLIENT_INIT_PROPS
+/*     structure that was created by tls_proxy_client_init_scan().
+/*
+/*     TLS_CLIENT_INIT_PROPS *init_props = 0;
+/*     ...
+/*     ... RECV_ATTR_FUNC(tls_proxy_client_init_scan, (void *) &init_props)
+/*     ...
+/*     if (init_props != 0)
+/*         tls_proxy_client_init_free(init_props);
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     Google, Inc.
+/*     111 8th Avenue
+/*     New York, NY 10011, USA
+/*--*/
+
+#ifdef USE_TLS
+
+/* System library. */
+
+#include <sys_defs.h>
+
+/* Utility library */
+
+#include <attr.h>
+#include <argv_attr.h>
+#include <msg.h>
+
+/* Global library. */
+
+#include <mail_params.h>
+
+/* TLS library. */
+
+#define TLS_INTERNAL
+#include <tls.h>
+#include <tls_proxy_attr.h>
+#include <tls_proxy_client_init_proto.h>
+
+#ifdef USE_TLSRPT
+#define TLSRPT_WRAPPER_INTERNAL
+#include <tlsrpt_wrapper.h>
+#endif
+
+#define STR(x) vstring_str(x)
+#define LEN(x) VSTRING_LEN(x)
+
+/* tls_proxy_client_init_serialize - serialize to string */
+
+char   *tls_proxy_client_init_serialize(ATTR_PRINT_COMMON_FN print_fn,
+                                               VSTRING *buf,
+                                        const TLS_CLIENT_INIT_PROPS *props)
+{
+    const char myname[] = "tls_proxy_client_init_serialize";
+    VSTREAM *mp;
+
+    if ((mp = vstream_memopen(buf, O_WRONLY)) == 0
+       || print_fn(mp, ATTR_FLAG_NONE,
+                   SEND_ATTR_FUNC(tls_proxy_client_init_print,
+                                  (const void *) props),
+                   ATTR_TYPE_END) != 0
+       || vstream_fclose(mp) != 0)
+       msg_fatal("%s: can't serialize properties: %m", myname);
+    return (vstring_str(buf));
+}
+
+/* tls_proxy_client_init_from_string - deserialize TLS_CLIENT_INIT_PROPS */
+
+TLS_CLIENT_INIT_PROPS *tls_proxy_client_init_from_string(
+                                               ATTR_SCAN_COMMON_FN scan_fn,
+                                                            VSTRING *buf)
+{
+    const char myname[] = "tls_proxy_client_init_from_string";
+    TLS_CLIENT_INIT_PROPS *props = 0;
+    VSTREAM *mp;
+
+    if ((mp = vstream_memopen(buf, O_RDONLY)) == 0
+       || scan_fn(mp, ATTR_FLAG_NONE,
+                  RECV_ATTR_FUNC(tls_proxy_client_init_scan,
+                                 (void *) &props),
+                  ATTR_TYPE_END) != 1
+       || vstream_fclose(mp) != 0)
+       msg_fatal("%s: can't deserialize properties: %m", myname);
+    return (props);
+}
+
+/* tls_proxy_client_init_print - send TLS_CLIENT_INIT_PROPS over stream */
+
+int     tls_proxy_client_init_print(ATTR_PRINT_COMMON_FN print_fn, VSTREAM *fp,
+                                           int flags, const void *ptr)
+{
+    const TLS_CLIENT_INIT_PROPS *props = (const TLS_CLIENT_INIT_PROPS *) ptr;
+    int     ret;
+
+    if (msg_verbose)
+       msg_info("begin tls_proxy_client_init_print");
+
+#define STRING_OR_EMPTY(s) ((s) ? (s) : "")
+
+    ret = print_fn(fp, flags | ATTR_FLAG_MORE,
+                  SEND_ATTR_STR(TLS_ATTR_LOG_PARAM,
+                                STRING_OR_EMPTY(props->log_param)),
+                  SEND_ATTR_STR(TLS_ATTR_LOG_LEVEL,
+                                STRING_OR_EMPTY(props->log_level)),
+                  SEND_ATTR_INT(TLS_ATTR_VERIFYDEPTH, props->verifydepth),
+                  SEND_ATTR_STR(TLS_ATTR_CACHE_TYPE,
+                                STRING_OR_EMPTY(props->cache_type)),
+                  SEND_ATTR_STR(TLS_ATTR_CHAIN_FILES,
+                                STRING_OR_EMPTY(props->chain_files)),
+                  SEND_ATTR_STR(TLS_ATTR_CERT_FILE,
+                                STRING_OR_EMPTY(props->cert_file)),
+                  SEND_ATTR_STR(TLS_ATTR_KEY_FILE,
+                                STRING_OR_EMPTY(props->key_file)),
+                  SEND_ATTR_STR(TLS_ATTR_DCERT_FILE,
+                                STRING_OR_EMPTY(props->dcert_file)),
+                  SEND_ATTR_STR(TLS_ATTR_DKEY_FILE,
+                                STRING_OR_EMPTY(props->dkey_file)),
+                  SEND_ATTR_STR(TLS_ATTR_ECCERT_FILE,
+                                STRING_OR_EMPTY(props->eccert_file)),
+                  SEND_ATTR_STR(TLS_ATTR_ECKEY_FILE,
+                                STRING_OR_EMPTY(props->eckey_file)),
+                  SEND_ATTR_STR(TLS_ATTR_CAFILE,
+                                STRING_OR_EMPTY(props->CAfile)),
+                  SEND_ATTR_STR(TLS_ATTR_CAPATH,
+                                STRING_OR_EMPTY(props->CApath)),
+                  SEND_ATTR_STR(TLS_ATTR_MDALG,
+                                STRING_OR_EMPTY(props->mdalg)),
+                  ATTR_TYPE_END);
+    /* Do not flush the stream. */
+    if (msg_verbose)
+       msg_info("tls_proxy_client_init_print ret=%d", ret);
+    return (ret);
+}
+
+/* tls_proxy_client_init_free - destroy TLS_CLIENT_INIT_PROPS structure */
+
+void    tls_proxy_client_init_free(TLS_CLIENT_INIT_PROPS *props)
+{
+    myfree((void *) props->log_param);
+    myfree((void *) props->log_level);
+    myfree((void *) props->cache_type);
+    myfree((void *) props->chain_files);
+    myfree((void *) props->cert_file);
+    myfree((void *) props->key_file);
+    myfree((void *) props->dcert_file);
+    myfree((void *) props->dkey_file);
+    myfree((void *) props->eccert_file);
+    myfree((void *) props->eckey_file);
+    myfree((void *) props->CAfile);
+    myfree((void *) props->CApath);
+    myfree((void *) props->mdalg);
+    myfree((void *) props);
+}
+
+/* tls_proxy_client_init_scan - receive TLS_CLIENT_INIT_PROPS from stream */
+
+int     tls_proxy_client_init_scan(ATTR_SCAN_COMMON_FN scan_fn, VSTREAM *fp,
+                                          int flags, void *ptr)
+{
+    TLS_CLIENT_INIT_PROPS *props
+    = (TLS_CLIENT_INIT_PROPS *) mymalloc(sizeof(*props));
+    int     ret;
+    VSTRING *log_param = vstring_alloc(25);
+    VSTRING *log_level = vstring_alloc(25);
+    VSTRING *cache_type = vstring_alloc(25);
+    VSTRING *chain_files = vstring_alloc(25);
+    VSTRING *cert_file = vstring_alloc(25);
+    VSTRING *key_file = vstring_alloc(25);
+    VSTRING *dcert_file = vstring_alloc(25);
+    VSTRING *dkey_file = vstring_alloc(25);
+    VSTRING *eccert_file = vstring_alloc(25);
+    VSTRING *eckey_file = vstring_alloc(25);
+    VSTRING *CAfile = vstring_alloc(25);
+    VSTRING *CApath = vstring_alloc(25);
+    VSTRING *mdalg = vstring_alloc(25);
+
+    if (msg_verbose)
+       msg_info("begin tls_proxy_client_init_scan");
+
+    /*
+     * Note: memset() is not a portable way to initialize non-integer types.
+     */
+    memset(props, 0, sizeof(*props));
+    ret = scan_fn(fp, flags | ATTR_FLAG_MORE,
+                 RECV_ATTR_STR(TLS_ATTR_LOG_PARAM, log_param),
+                 RECV_ATTR_STR(TLS_ATTR_LOG_LEVEL, log_level),
+                 RECV_ATTR_INT(TLS_ATTR_VERIFYDEPTH, &props->verifydepth),
+                 RECV_ATTR_STR(TLS_ATTR_CACHE_TYPE, cache_type),
+                 RECV_ATTR_STR(TLS_ATTR_CHAIN_FILES, chain_files),
+                 RECV_ATTR_STR(TLS_ATTR_CERT_FILE, cert_file),
+                 RECV_ATTR_STR(TLS_ATTR_KEY_FILE, key_file),
+                 RECV_ATTR_STR(TLS_ATTR_DCERT_FILE, dcert_file),
+                 RECV_ATTR_STR(TLS_ATTR_DKEY_FILE, dkey_file),
+                 RECV_ATTR_STR(TLS_ATTR_ECCERT_FILE, eccert_file),
+                 RECV_ATTR_STR(TLS_ATTR_ECKEY_FILE, eckey_file),
+                 RECV_ATTR_STR(TLS_ATTR_CAFILE, CAfile),
+                 RECV_ATTR_STR(TLS_ATTR_CAPATH, CApath),
+                 RECV_ATTR_STR(TLS_ATTR_MDALG, mdalg),
+                 ATTR_TYPE_END);
+    /* Always construct a well-formed structure. */
+    props->log_param = vstring_export(log_param);
+    props->log_level = vstring_export(log_level);
+    props->cache_type = vstring_export(cache_type);
+    props->chain_files = vstring_export(chain_files);
+    props->cert_file = vstring_export(cert_file);
+    props->key_file = vstring_export(key_file);
+    props->dcert_file = vstring_export(dcert_file);
+    props->dkey_file = vstring_export(dkey_file);
+    props->eccert_file = vstring_export(eccert_file);
+    props->eckey_file = vstring_export(eckey_file);
+    props->CAfile = vstring_export(CAfile);
+    props->CApath = vstring_export(CApath);
+    props->mdalg = vstring_export(mdalg);
+    ret = (ret == 14 ? 1 : -1);
+    if (ret != 1) {
+       tls_proxy_client_init_free(props);
+       props = 0;
+    }
+    *(TLS_CLIENT_INIT_PROPS **) ptr = props;
+    if (msg_verbose)
+       msg_info("tls_proxy_client_init_scan ret=%d", ret);
+    return (ret);
+}
+
+#endif
diff --git a/postfix/src/tls/tls_proxy_client_init_proto.h b/postfix/src/tls/tls_proxy_client_init_proto.h
new file mode 100644 (file)
index 0000000..c5b063c
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef _TLS_PROXY_CLIENT_INIT_PROTO_H_INCLUDED_
+#define _TLS_PROXY_CLIENT_INIT_PROTO_H_INCLUDED_
+
+/*++
+/* NAME
+/*     tls_proxy_client_init_proto 3h
+/* SUMMARY
+/*     TLS_CLIENT_START support
+/* SYNOPSIS
+/*     #include <tls_proxy_client_init_proto.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <vstream.h>
+#include <attr.h>
+
+ /*
+  * TLS library.
+  */
+#include <tls.h>
+
+#ifdef USE_TLS
+
+#define TLS_PROXY_CLIENT_INIT_PROPS(props, a1, a2, a3, a4, a5, a6, a7, a8, \
+    a9, a10, a11, a12, a13, a14) \
+    (((props)->a1), ((props)->a2), ((props)->a3), \
+    ((props)->a4), ((props)->a5), ((props)->a6), ((props)->a7), \
+    ((props)->a8), ((props)->a9), ((props)->a10), ((props)->a11), \
+    ((props)->a12), ((props)->a13), ((props)->a14))
+
+extern char *tls_proxy_client_init_serialize(ATTR_PRINT_COMMON_FN, VSTRING *, const TLS_CLIENT_INIT_PROPS *);
+extern TLS_CLIENT_INIT_PROPS *tls_proxy_client_init_from_string(ATTR_SCAN_COMMON_FN, VSTRING *);
+extern int tls_proxy_client_init_print(ATTR_PRINT_COMMON_FN, VSTREAM *, int, const void *);
+extern void tls_proxy_client_init_free(TLS_CLIENT_INIT_PROPS *);
+extern int tls_proxy_client_init_scan(ATTR_SCAN_COMMON_FN, VSTREAM *, int, void *);
+
+#endif                                 /* USE_TLS */
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*
+/*     Wietse Venema
+/*     Google, Inc.
+/*     111 8th Avenue
+/*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif
diff --git a/postfix/src/tls/tls_proxy_client_init_proto_test.c b/postfix/src/tls/tls_proxy_client_init_proto_test.c
new file mode 100644 (file)
index 0000000..1fbd643
--- /dev/null
@@ -0,0 +1,227 @@
+/*++
+/* NAME
+/*     tls_proxy_client_init_proto_test 1t
+/* SUMMARY
+/*     tls_proxy_client_init_proto unit test
+/* SYNOPSIS
+/*     ./tls_proxy_client_init_proto_test
+/* DESCRIPTION
+/*     tls_proxy_client_init_proto_test runs and logs each configured test, reports if
+/*     a test is a PASS or FAIL, and returns an exit status of zero if
+/*     all tests are a PASS.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+
+ /*
+  * Utility library.
+  */
+
+ /*
+  * Global library.
+  */
+#include <mail_params.h>
+
+ /*
+  * TLS library.
+  */
+#include <tls_proxy_client_init_proto.h>
+#include <tls_proxy_attr.h>
+
+ /*
+  * Test libraries.
+  */
+#include <ptest.h>
+#include <make_attr.h>
+#include <match_attr.h>
+
+ /*
+  * Test structure.
+  */
+typedef struct PTEST_CASE {
+    const char *testname;
+    void    (*action) (PTEST_CTX *, const struct PTEST_CASE *);
+} PTEST_CASE;
+
+#ifdef USE_TLS
+
+ /*
+  * Scaffolding: configuration parameters.
+  */
+char   *var_smtp_tls_loglevel;
+int     var_smtp_tls_scert_vd;
+static char *cache_type;
+char   *var_smtp_tls_chain_files;
+char   *var_smtp_tls_cert_file;
+char   *var_smtp_tls_key_file;
+char   *var_smtp_tls_dcert_file;
+char   *var_smtp_tls_dkey_file;
+char   *var_smtp_tls_eccert_file;
+char   *var_smtp_tls_eckey_file;
+char   *var_smtp_tls_CAfile;
+char   *var_smtp_tls_CApath;
+char   *var_smtp_tls_fpt_dgst;
+
+static void init_global_params(void)
+{
+    var_smtp_tls_loglevel = DEF_SMTP_TLS_LOGLEVEL;
+    var_smtp_tls_scert_vd = DEF_SMTP_TLS_SCERT_VD;
+    cache_type = TLS_MGR_SCACHE_SMTP;
+    var_smtp_tls_chain_files = DEF_SMTP_TLS_CHAIN_FILES;
+    var_smtp_tls_cert_file = DEF_SMTP_TLS_CERT_FILE;
+    var_smtp_tls_key_file = DEF_SMTP_TLS_CERT_FILE;
+    var_smtp_tls_dcert_file = DEF_SMTP_TLS_DCERT_FILE;
+    var_smtp_tls_dkey_file = DEF_SMTP_TLS_DCERT_FILE;
+    var_smtp_tls_eccert_file = DEF_SMTP_TLS_ECCERT_FILE;
+    var_smtp_tls_eckey_file = DEF_SMTP_TLS_ECCERT_FILE;
+    var_smtp_tls_CAfile = DEF_SMTP_TLS_CA_FILE;
+    var_smtp_tls_CApath = DEF_SMTP_TLS_CA_PATH;
+    var_smtp_tls_fpt_dgst = DEF_SMTP_TLS_FPT_DGST;
+}
+
+static void setup_reference_unserialized_init_props(TLS_CLIENT_INIT_PROPS *props)
+{
+    TLS_PROXY_CLIENT_INIT_PROPS(props,
+                               log_param = VAR_SMTP_TLS_LOGLEVEL,
+                               log_level = var_smtp_tls_loglevel,
+                               verifydepth = var_smtp_tls_scert_vd,
+                               cache_type = cache_type,
+                               chain_files = var_smtp_tls_chain_files,
+                               cert_file = var_smtp_tls_cert_file,
+                               key_file = var_smtp_tls_key_file,
+                               dcert_file = var_smtp_tls_dcert_file,
+                               dkey_file = var_smtp_tls_dkey_file,
+                               eccert_file = var_smtp_tls_eccert_file,
+                               eckey_file = var_smtp_tls_eckey_file,
+                               CAfile = var_smtp_tls_CAfile,
+                               CApath = var_smtp_tls_CApath,
+                               mdalg = var_smtp_tls_fpt_dgst);
+}
+
+static VSTRING *setup_reference_serialized_init_props(TLS_CLIENT_INIT_PROPS *props)
+{
+
+    /*
+     * Note: this code is used to verify tls_proxy_client_init_print(), so we
+     * do not use that function here.
+     */
+#define STRING_OR_EMPTY(s) ((s) ? (s) : "")
+
+    return (make_attr(attr_vprint, ATTR_FLAG_NONE,
+                     SEND_ATTR_STR(TLS_ATTR_LOG_PARAM,
+                                   STRING_OR_EMPTY(props->log_param)),
+                     SEND_ATTR_STR(TLS_ATTR_LOG_LEVEL,
+                                   STRING_OR_EMPTY(props->log_level)),
+                     SEND_ATTR_INT(TLS_ATTR_VERIFYDEPTH,
+                                   props->verifydepth),
+                     SEND_ATTR_STR(TLS_ATTR_CACHE_TYPE,
+                                   STRING_OR_EMPTY(props->cache_type)),
+                     SEND_ATTR_STR(TLS_ATTR_CHAIN_FILES,
+                                   STRING_OR_EMPTY(props->chain_files)),
+                     SEND_ATTR_STR(TLS_ATTR_CERT_FILE,
+                                   STRING_OR_EMPTY(props->cert_file)),
+                     SEND_ATTR_STR(TLS_ATTR_KEY_FILE,
+                                   STRING_OR_EMPTY(props->key_file)),
+                     SEND_ATTR_STR(TLS_ATTR_DCERT_FILE,
+                                   STRING_OR_EMPTY(props->dcert_file)),
+                     SEND_ATTR_STR(TLS_ATTR_DKEY_FILE,
+                                   STRING_OR_EMPTY(props->dkey_file)),
+                     SEND_ATTR_STR(TLS_ATTR_ECCERT_FILE,
+                                   STRING_OR_EMPTY(props->eccert_file)),
+                     SEND_ATTR_STR(TLS_ATTR_ECKEY_FILE,
+                                   STRING_OR_EMPTY(props->eckey_file)),
+                     SEND_ATTR_STR(TLS_ATTR_CAFILE,
+                                   STRING_OR_EMPTY(props->CAfile)),
+                     SEND_ATTR_STR(TLS_ATTR_CAPATH,
+                                   STRING_OR_EMPTY(props->CApath)),
+                     SEND_ATTR_STR(TLS_ATTR_MDALG,
+                                   STRING_OR_EMPTY(props->mdalg)),
+                     ATTR_TYPE_END));
+}
+
+#endif
+
+/* Note: this also tests tls_proxy_client_init_print() */
+
+static void test_tls_proxy_client_init_serialize(PTEST_CTX *t,
+                                           const struct PTEST_CASE *unused)
+{
+#ifdef USE_TLS
+    TLS_CLIENT_INIT_PROPS ref_unserialized_init_props;
+    VSTRING *got_serialized_init_props;
+    VSTRING *ref_serialized_init_props;
+
+    init_global_params();
+
+    setup_reference_unserialized_init_props(&ref_unserialized_init_props);
+
+    ref_serialized_init_props = setup_reference_serialized_init_props(
+                                             &ref_unserialized_init_props);
+
+    tls_proxy_client_init_serialize(attr_print,
+                            got_serialized_init_props = vstring_alloc(100),
+                              (const void *) &ref_unserialized_init_props);
+
+    (void) eq_attr(t, "tls_proxy_client_init_serialize",
+                  got_serialized_init_props, ref_serialized_init_props);
+#else
+    ptest_skip(t);
+#endif
+}
+
+/* Note: this also tests tls_proxy_client_init_scan() */
+
+static void test_tls_proxy_client_init_from_string(PTEST_CTX *t,
+                                           const struct PTEST_CASE *unused)
+{
+#ifdef USE_TLS
+    TLS_CLIENT_INIT_PROPS ref_unserialized_init_props;
+    VSTRING *ref_serialized_init_props;
+    VSTRING *got_serialized_init_props;
+    TLS_CLIENT_INIT_PROPS *deserialized_init_props;
+
+    init_global_params();
+
+    setup_reference_unserialized_init_props(&ref_unserialized_init_props);
+
+    ref_serialized_init_props = setup_reference_serialized_init_props(
+                                             &ref_unserialized_init_props);
+
+    deserialized_init_props = tls_proxy_client_init_from_string(attr_scan,
+                                                ref_serialized_init_props);
+    if (deserialized_init_props == 0)
+       ptest_fatal(t, "tls_proxy_client_init_from_string failed");
+
+    tls_proxy_client_init_serialize(attr_print,
+                            got_serialized_init_props = vstring_alloc(100),
+                                   deserialized_init_props);
+
+    eq_attr(t, "tls_proxy_client_init_from_string",
+           got_serialized_init_props, ref_serialized_init_props);
+
+    vstring_free(ref_serialized_init_props);
+    vstring_free(got_serialized_init_props);
+#else
+    ptest_skip(t);
+#endif
+}
+
+ /*
+  * The list of test cases.
+  */
+static const PTEST_CASE ptestcases[] = {
+    "test_tls_proxy_client_init_serialize", test_tls_proxy_client_init_serialize,
+    "test_tls_proxy_client_init_from_string", test_tls_proxy_client_init_from_string,
+};
+
+#include <ptest_main.h>
diff --git a/postfix/src/tls/tls_proxy_client_misc.c b/postfix/src/tls/tls_proxy_client_misc.c
deleted file mode 100644 (file)
index 45a0e0b..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*++
-/* NAME
-/*     tls_proxy_client_misc 3
-/* SUMMARY
-/*     TLS_CLIENT_XXX structure support
-/* SYNOPSIS
-/*     #include <tls_proxy.h>
-/*
-/*     TLS_CLIENT_PARAMS *tls_proxy_client_param_from_config(params)
-/*     TLS_CLIENT_PARAMS *params;
-/*
-/*     char    *tls_proxy_client_param_serialize(print_fn, buf, params)
-/*     ATTR_PRINT_COMMON_FN print_fn;
-/*     VSTRING *buf;
-/*     const TLS_CLIENT_PARAMS *params;
-/*
-/*     char    *tls_proxy_client_init_serialize(print_fn, buf, init_props)
-/*     ATTR_PRINT_COMMON_FN print_fn;
-/*     VSTRING *buf;
-/*     const TLS_CLIENT_INIT_PROPS *init_props;
-/* DESCRIPTION
-/*     tls_proxy_client_param_from_config() initializes a TLS_CLIENT_PARAMS
-/*     structure from configuration parameters and returns its
-/*     argument. Strings are not copied. The result must therefore
-/*     not be passed to tls_proxy_client_param_free().
-/*
-/*     tls_proxy_client_param_serialize() and
-/*     tls_proxy_client_init_serialize() serialize the specified
-/*     object to a memory buffer, using the specified print function
-/*     (typically, attr_print_plain). The result can be used
-/*     determine whether there are any differences between instances
-/*     of the same object type.
-/* LICENSE
-/* .ad
-/* .fi
-/*     The Secure Mailer license must be distributed with this software.
-/* AUTHOR(S)
-/*     Wietse Venema
-/*     Google, Inc.
-/*     111 8th Avenue
-/*     New York, NY 10011, USA
-/*--*/
-
-#ifdef USE_TLS
-
-/* System library. */
-
-#include <sys_defs.h>
-
-/* Utility library */
-
-#include <attr.h>
-#include <msg.h>
-
-/* Global library. */
-
-#include <mail_params.h>
-
-/* TLS library. */
-
-#include <tls.h>
-#include <tls_proxy.h>
-
-/* tls_proxy_client_param_from_config - initialize TLS_CLIENT_PARAMS from configuration */
-
-TLS_CLIENT_PARAMS *tls_proxy_client_param_from_config(TLS_CLIENT_PARAMS *params)
-{
-    TLS_PROXY_PARAMS(params,
-                    tls_cnf_file = var_tls_cnf_file,
-                    tls_cnf_name = var_tls_cnf_name,
-                    tls_high_clist = var_tls_high_clist,
-                    tls_medium_clist = var_tls_medium_clist,
-                    tls_null_clist = var_tls_null_clist,
-                    tls_eecdh_auto = var_tls_eecdh_auto,
-                    tls_eecdh_strong = var_tls_eecdh_strong,
-                    tls_eecdh_ultra = var_tls_eecdh_ultra,
-                    tls_ffdhe_auto = var_tls_ffdhe_auto,
-                    tls_bug_tweaks = var_tls_bug_tweaks,
-                    tls_ssl_options = var_tls_ssl_options,
-                    tls_dane_digests = var_tls_dane_digests,
-                    tls_mgr_service = var_tls_mgr_service,
-                    tls_tkt_cipher = var_tls_tkt_cipher,
-                    tls_daemon_rand_bytes = var_tls_daemon_rand_bytes,
-                    tls_append_def_CA = var_tls_append_def_CA,
-                    tls_preempt_clist = var_tls_preempt_clist,
-                    tls_multi_wildcard = var_tls_multi_wildcard);
-    return (params);
-}
-
-/* tls_proxy_client_param_serialize - serialize TLS_CLIENT_PARAMS to string */
-
-char   *tls_proxy_client_param_serialize(ATTR_PRINT_COMMON_FN print_fn,
-                                                VSTRING *buf,
-                                           const TLS_CLIENT_PARAMS *params)
-{
-    const char myname[] = "tls_proxy_client_param_serialize";
-    VSTREAM *mp;
-
-    if ((mp = vstream_memopen(buf, O_WRONLY)) == 0
-       || print_fn(mp, ATTR_FLAG_NONE,
-                   SEND_ATTR_FUNC(tls_proxy_client_param_print,
-                                  (const void *) params),
-                   ATTR_TYPE_END) != 0
-       || vstream_fclose(mp) != 0)
-       msg_fatal("%s: can't serialize properties: %m", myname);
-    return (vstring_str(buf));
-}
-
-/* tls_proxy_client_init_serialize - serialize to string */
-
-char   *tls_proxy_client_init_serialize(ATTR_PRINT_COMMON_FN print_fn,
-                                               VSTRING *buf,
-                                        const TLS_CLIENT_INIT_PROPS *props)
-{
-    const char myname[] = "tls_proxy_client_init_serialize";
-    VSTREAM *mp;
-
-    if ((mp = vstream_memopen(buf, O_WRONLY)) == 0
-       || print_fn(mp, ATTR_FLAG_NONE,
-                   SEND_ATTR_FUNC(tls_proxy_client_init_print,
-                                  (const void *) props),
-                   ATTR_TYPE_END) != 0
-       || vstream_fclose(mp) != 0)
-       msg_fatal("%s: can't serialize properties: %m", myname);
-    return (vstring_str(buf));
-}
-
-#endif
diff --git a/postfix/src/tls/tls_proxy_client_param_proto.c b/postfix/src/tls/tls_proxy_client_param_proto.c
new file mode 100644 (file)
index 0000000..b9bdb86
--- /dev/null
@@ -0,0 +1,327 @@
+/*++
+/* NAME
+/*     tls_proxy_client_param_proto 3
+/* SUMMARY
+/*     TLS_CLIENT_PARAMS structure support
+/* SYNOPSIS
+/*     #include <tls_proxy_client_param_proto.h>
+/*
+/*     TLS_CLIENT_PARAMS *tls_proxy_client_param_from_config(params)
+/*     TLS_CLIENT_PARAMS *params;
+/*
+/*     char    *tls_proxy_client_param_serialize(print_fn, buf, params)
+/*     ATTR_PRINT_COMMON_FN print_fn;
+/*     VSTRING *buf;
+/*     const TLS_CLIENT_PARAMS *params;
+/*
+/*     TLS_CLIENT_PARAMS *tls_proxy_client_param_from_string(
+/*     ATTR_SCAN_COMMON_FN scan_fn,
+/*     const VSTRING *buf)
+/*
+/*     int     tls_proxy_client_param_print(print_fn, stream, flags, ptr)
+/*     ATTR_PRINT_COMMON_FN print_fn;
+/*     VSTREAM *stream;
+/*     int     flags;
+/*     const void *ptr;
+/*
+/*     int     tls_proxy_client_param_scan(scan_fn, stream, flags, ptr)
+/*     ATTR_SCAN_COMMON_FN scan_fn;
+/*     VSTREAM *stream;
+/*     int     flags;
+/*     void    *ptr;
+/*
+/*     void    tls_proxy_client_param_free(params)
+/*     TLS_CLIENT_PARAMS *params;
+/* DESCRIPTION
+/*     tls_proxy_client_param_from_config() initializes a TLS_CLIENT_PARAMS
+/*     structure from configuration parameters and returns its
+/*     argument. Strings are not copied. The result must therefore
+/*     not be passed to tls_proxy_client_param_free().
+/*
+/*     tls_proxy_client_param_serialize() serializes the specified
+/*     object to a memory buffer, using the specified print function
+/*     (typically, attr_print_plain). The result can be used
+/*     determine whether there are any differences between instances
+/*     of the same object type.
+/*
+/*     tls_proxy_client_param_from_string() deserializes the specified
+/*     buffer into a TLS_CLIENT_PARAMS object, and returns null in case
+/*     of error. The result if not null should be passed to
+/*     tls_proxy_client_param_free().
+/*
+/*     tls_proxy_client_param_print() writes a TLS_CLIENT_PARAMS structure to
+/*     the named stream using the specified attribute print routine.
+/*     tls_proxy_client_param_print() is meant to be passed as a call-back to
+/*     attr_print(), thusly:
+/*
+/*     SEND_ATTR_FUNC(tls_proxy_client_param_print, (const void *) param), ...
+/*
+/*     tls_proxy_client_param_scan() reads a TLS_CLIENT_PARAMS structure from
+/*     the named stream using the specified attribute scan routine.
+/*     tls_proxy_client_param_scan() is meant to be passed as a call-back
+/*     function to attr_scan(), as shown below.
+/*
+/*     tls_proxy_client_param_free() destroys a TLS_CLIENT_PARAMS structure
+/*     that was created by tls_proxy_client_param_scan().
+/*
+/*     TLS_CLIENT_PARAMS *param = 0;
+/*     ...
+/*     ... RECV_ATTR_FUNC(tls_proxy_client_param_scan, (void *) &param)
+/*     ...
+/*     if (param != 0)
+/*         tls_proxy_client_param_free(param);
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     Google, Inc.
+/*     111 8th Avenue
+/*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#ifdef USE_TLS
+
+/* System library. */
+
+#include <sys_defs.h>
+
+/* Utility library */
+
+#include <attr.h>
+#include <msg.h>
+
+/* Global library. */
+
+#include <mail_params.h>
+
+/* TLS library. */
+
+#include <tls.h>
+#include <tls_proxy_attr.h>
+#include <tls_proxy_client_param_proto.h>
+
+/* tls_proxy_client_param_from_config - initialize TLS_CLIENT_PARAMS from configuration */
+
+TLS_CLIENT_PARAMS *tls_proxy_client_param_from_config(TLS_CLIENT_PARAMS *params)
+{
+    TLS_PROXY_CLIENT_PARAMS(params,
+                           tls_cnf_file = var_tls_cnf_file,
+                           tls_cnf_name = var_tls_cnf_name,
+                           tls_high_clist = var_tls_high_clist,
+                           tls_medium_clist = var_tls_medium_clist,
+                           tls_null_clist = var_tls_null_clist,
+                           tls_eecdh_auto = var_tls_eecdh_auto,
+                           tls_eecdh_strong = var_tls_eecdh_strong,
+                           tls_eecdh_ultra = var_tls_eecdh_ultra,
+                           tls_ffdhe_auto = var_tls_ffdhe_auto,
+                           tls_bug_tweaks = var_tls_bug_tweaks,
+                           tls_ssl_options = var_tls_ssl_options,
+                           tls_dane_digests = var_tls_dane_digests,
+                           tls_mgr_service = var_tls_mgr_service,
+                           tls_tkt_cipher = var_tls_tkt_cipher,
+                         tls_daemon_rand_bytes = var_tls_daemon_rand_bytes,
+                           tls_append_def_CA = var_tls_append_def_CA,
+                           tls_preempt_clist = var_tls_preempt_clist,
+                           tls_multi_wildcard = var_tls_multi_wildcard,
+                           tls_fast_shutdown = var_tls_fast_shutdown);
+    return (params);
+}
+
+/* tls_proxy_client_param_serialize - serialize TLS_CLIENT_PARAMS to string */
+
+char   *tls_proxy_client_param_serialize(ATTR_PRINT_COMMON_FN print_fn,
+                                                VSTRING *buf,
+                                           const TLS_CLIENT_PARAMS *params)
+{
+    const char myname[] = "tls_proxy_client_param_serialize";
+    VSTREAM *mp;
+
+    if ((mp = vstream_memopen(buf, O_WRONLY)) == 0
+       || print_fn(mp, ATTR_FLAG_NONE,
+                   SEND_ATTR_FUNC(tls_proxy_client_param_print,
+                                  (const void *) params),
+                   ATTR_TYPE_END) != 0
+       || vstream_fclose(mp) != 0)
+       msg_fatal("%s: can't serialize properties: %m", myname);
+    return (vstring_str(buf));
+}
+
+/* tls_proxy_client_param_from_string - deserialize TLS_CLIENT_PARAMS */
+
+TLS_CLIENT_PARAMS *tls_proxy_client_param_from_string(
+                                               ATTR_SCAN_COMMON_FN scan_fn,
+                                                             VSTRING *buf)
+{
+    const char myname[] = "tls_proxy_client_param_from_string";
+    TLS_CLIENT_PARAMS *params = 0;
+    VSTREAM *mp;
+
+    if ((mp = vstream_memopen(buf, O_RDONLY)) == 0
+       || scan_fn(mp, ATTR_FLAG_NONE,
+                  RECV_ATTR_FUNC(tls_proxy_client_param_scan,
+                                 (void *) &params),
+                  ATTR_TYPE_END) != 1
+       || vstream_fclose(mp) != 0)
+       msg_fatal("%s: can't deserialize properties: %m", myname);
+    return (params);
+}
+
+/* tls_proxy_client_param_print - send TLS_CLIENT_PARAMS over stream */
+
+int     tls_proxy_client_param_print(ATTR_PRINT_COMMON_FN print_fn, VSTREAM *fp,
+                                            int flags, const void *ptr)
+{
+    const TLS_CLIENT_PARAMS *params = (const TLS_CLIENT_PARAMS *) ptr;
+    int     ret;
+
+    if (msg_verbose)
+       msg_info("begin tls_proxy_client_param_print");
+
+    ret = print_fn(fp, flags | ATTR_FLAG_MORE,
+                  SEND_ATTR_STR(TLS_ATTR_CNF_FILE, params->tls_cnf_file),
+                  SEND_ATTR_STR(TLS_ATTR_CNF_NAME, params->tls_cnf_name),
+                  SEND_ATTR_STR(VAR_TLS_HIGH_CLIST, params->tls_high_clist),
+                  SEND_ATTR_STR(VAR_TLS_MEDIUM_CLIST,
+                                params->tls_medium_clist),
+                  SEND_ATTR_STR(VAR_TLS_NULL_CLIST, params->tls_null_clist),
+                  SEND_ATTR_STR(VAR_TLS_EECDH_AUTO, params->tls_eecdh_auto),
+                  SEND_ATTR_STR(VAR_TLS_EECDH_STRONG,
+                                params->tls_eecdh_strong),
+                  SEND_ATTR_STR(VAR_TLS_EECDH_ULTRA,
+                                params->tls_eecdh_ultra),
+                  SEND_ATTR_STR(VAR_TLS_FFDHE_AUTO, params->tls_ffdhe_auto),
+                  SEND_ATTR_STR(VAR_TLS_BUG_TWEAKS, params->tls_bug_tweaks),
+                  SEND_ATTR_STR(VAR_TLS_SSL_OPTIONS,
+                                params->tls_ssl_options),
+                  SEND_ATTR_STR(VAR_TLS_DANE_DIGESTS,
+                                params->tls_dane_digests),
+                  SEND_ATTR_STR(VAR_TLS_MGR_SERVICE,
+                                params->tls_mgr_service),
+                  SEND_ATTR_STR(VAR_TLS_TKT_CIPHER, params->tls_tkt_cipher),
+                  SEND_ATTR_INT(VAR_TLS_DAEMON_RAND_BYTES,
+                                params->tls_daemon_rand_bytes),
+                  SEND_ATTR_INT(VAR_TLS_APPEND_DEF_CA,
+                                params->tls_append_def_CA),
+                  SEND_ATTR_INT(VAR_TLS_PREEMPT_CLIST,
+                                params->tls_preempt_clist),
+                  SEND_ATTR_INT(VAR_TLS_MULTI_WILDCARD,
+                                params->tls_multi_wildcard),
+                  SEND_ATTR_INT(VAR_TLS_FAST_SHUTDOWN,
+                                params->tls_fast_shutdown),
+                  ATTR_TYPE_END);
+    /* Do not flush the stream. */
+    if (msg_verbose)
+       msg_info("tls_proxy_client_param_print ret=%d", ret);
+    return (ret);
+}
+
+/* tls_proxy_client_param_free - destroy TLS_CLIENT_PARAMS structure */
+
+void    tls_proxy_client_param_free(TLS_CLIENT_PARAMS *params)
+{
+    myfree(params->tls_cnf_file);
+    myfree(params->tls_cnf_name);
+    myfree(params->tls_high_clist);
+    myfree(params->tls_medium_clist);
+    myfree(params->tls_null_clist);
+    myfree(params->tls_eecdh_auto);
+    myfree(params->tls_eecdh_strong);
+    myfree(params->tls_eecdh_ultra);
+    myfree(params->tls_ffdhe_auto);
+    myfree(params->tls_bug_tweaks);
+    myfree(params->tls_ssl_options);
+    myfree(params->tls_dane_digests);
+    myfree(params->tls_mgr_service);
+    myfree(params->tls_tkt_cipher);
+    myfree((void *) params);
+}
+
+/* tls_proxy_client_param_scan - receive TLS_CLIENT_PARAMS from stream */
+
+int     tls_proxy_client_param_scan(ATTR_SCAN_COMMON_FN scan_fn, VSTREAM *fp,
+                                           int flags, void *ptr)
+{
+    TLS_CLIENT_PARAMS *params
+    = (TLS_CLIENT_PARAMS *) mymalloc(sizeof(*params));
+    int     ret;
+    VSTRING *cnf_file = vstring_alloc(25);
+    VSTRING *cnf_name = vstring_alloc(25);
+    VSTRING *tls_high_clist = vstring_alloc(25);
+    VSTRING *tls_medium_clist = vstring_alloc(25);
+    VSTRING *tls_null_clist = vstring_alloc(25);
+    VSTRING *tls_eecdh_auto = vstring_alloc(25);
+    VSTRING *tls_eecdh_strong = vstring_alloc(25);
+    VSTRING *tls_eecdh_ultra = vstring_alloc(25);
+    VSTRING *tls_ffdhe_auto = vstring_alloc(25);
+    VSTRING *tls_bug_tweaks = vstring_alloc(25);
+    VSTRING *tls_ssl_options = vstring_alloc(25);
+    VSTRING *tls_dane_digests = vstring_alloc(25);
+    VSTRING *tls_mgr_service = vstring_alloc(25);
+    VSTRING *tls_tkt_cipher = vstring_alloc(25);
+
+    if (msg_verbose)
+       msg_info("begin tls_proxy_client_param_scan");
+
+    /*
+     * Note: memset() is not a portable way to initialize non-integer types.
+     */
+    memset(params, 0, sizeof(*params));
+    ret = scan_fn(fp, flags | ATTR_FLAG_MORE,
+                 RECV_ATTR_STR(TLS_ATTR_CNF_FILE, cnf_file),
+                 RECV_ATTR_STR(TLS_ATTR_CNF_NAME, cnf_name),
+                 RECV_ATTR_STR(VAR_TLS_HIGH_CLIST, tls_high_clist),
+                 RECV_ATTR_STR(VAR_TLS_MEDIUM_CLIST, tls_medium_clist),
+                 RECV_ATTR_STR(VAR_TLS_NULL_CLIST, tls_null_clist),
+                 RECV_ATTR_STR(VAR_TLS_EECDH_AUTO, tls_eecdh_auto),
+                 RECV_ATTR_STR(VAR_TLS_EECDH_STRONG, tls_eecdh_strong),
+                 RECV_ATTR_STR(VAR_TLS_EECDH_ULTRA, tls_eecdh_ultra),
+                 RECV_ATTR_STR(VAR_TLS_FFDHE_AUTO, tls_ffdhe_auto),
+                 RECV_ATTR_STR(VAR_TLS_BUG_TWEAKS, tls_bug_tweaks),
+                 RECV_ATTR_STR(VAR_TLS_SSL_OPTIONS, tls_ssl_options),
+                 RECV_ATTR_STR(VAR_TLS_DANE_DIGESTS, tls_dane_digests),
+                 RECV_ATTR_STR(VAR_TLS_MGR_SERVICE, tls_mgr_service),
+                 RECV_ATTR_STR(VAR_TLS_TKT_CIPHER, tls_tkt_cipher),
+                 RECV_ATTR_INT(VAR_TLS_DAEMON_RAND_BYTES,
+                               &params->tls_daemon_rand_bytes),
+                 RECV_ATTR_INT(VAR_TLS_APPEND_DEF_CA,
+                               &params->tls_append_def_CA),
+                 RECV_ATTR_INT(VAR_TLS_PREEMPT_CLIST,
+                               &params->tls_preempt_clist),
+                 RECV_ATTR_INT(VAR_TLS_MULTI_WILDCARD,
+                               &params->tls_multi_wildcard),
+                 RECV_ATTR_INT(VAR_TLS_FAST_SHUTDOWN,
+                               &params->tls_fast_shutdown),
+                 ATTR_TYPE_END);
+    /* Always construct a well-formed structure. */
+    params->tls_cnf_file = vstring_export(cnf_file);
+    params->tls_cnf_name = vstring_export(cnf_name);
+    params->tls_high_clist = vstring_export(tls_high_clist);
+    params->tls_medium_clist = vstring_export(tls_medium_clist);
+    params->tls_null_clist = vstring_export(tls_null_clist);
+    params->tls_eecdh_auto = vstring_export(tls_eecdh_auto);
+    params->tls_eecdh_strong = vstring_export(tls_eecdh_strong);
+    params->tls_eecdh_ultra = vstring_export(tls_eecdh_ultra);
+    params->tls_ffdhe_auto = vstring_export(tls_ffdhe_auto);
+    params->tls_bug_tweaks = vstring_export(tls_bug_tweaks);
+    params->tls_ssl_options = vstring_export(tls_ssl_options);
+    params->tls_dane_digests = vstring_export(tls_dane_digests);
+    params->tls_mgr_service = vstring_export(tls_mgr_service);
+    params->tls_tkt_cipher = vstring_export(tls_tkt_cipher);
+
+    ret = (ret == 19 ? 1 : -1);
+    if (ret != 1) {
+       tls_proxy_client_param_free(params);
+       params = 0;
+    }
+    *(TLS_CLIENT_PARAMS **) ptr = params;
+    if (msg_verbose)
+       msg_info("tls_proxy_client_param_scan ret=%d", ret);
+    return (ret);
+}
+
+#endif
diff --git a/postfix/src/tls/tls_proxy_client_param_proto.h b/postfix/src/tls/tls_proxy_client_param_proto.h
new file mode 100644 (file)
index 0000000..05887c1
--- /dev/null
@@ -0,0 +1,96 @@
+#ifndef _TLS_PROXY_CLIENT_PARAM_PROTO_H_INCLUDED_
+#define _TLS_PROXY_CLIENT_PARAM_PROTO_H_INCLUDED_
+
+/*++
+/* NAME
+/*     tls_proxy_client_param_proto 3h
+/* SUMMARY
+/*     TLS proxy protocol support
+/* SYNOPSIS
+/*     #include <tls_proxy_client_param_proto.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <vstream.h>
+#include <attr.h>
+
+ /*
+  * TLS library.
+  */
+#include <tls.h>
+
+#ifdef USE_TLS
+
+ /*
+  * TLS_CLIENT_PARAMS structure, to communicate global TLS library settings
+  * that are the same for all TLS client contexts. This information is used
+  * in tlsproxy(8) to detect inconsistencies. If this structure is changed,
+  * update all TLS_CLIENT_PARAMS related functions in tls_proxy_client_*.c.
+  * 
+  * In the serialization these attributes are identified by their configuration
+  * parameter names.
+  * 
+  * NOTE: this does not include openssl_path.
+  */
+typedef struct TLS_CLIENT_PARAMS {
+    char   *tls_cnf_file;
+    char   *tls_cnf_name;
+    char   *tls_high_clist;
+    char   *tls_medium_clist;
+    char   *tls_null_clist;
+    char   *tls_eecdh_auto;
+    char   *tls_eecdh_strong;
+    char   *tls_eecdh_ultra;
+    char   *tls_ffdhe_auto;
+    char   *tls_bug_tweaks;
+    char   *tls_ssl_options;
+    char   *tls_dane_digests;
+    char   *tls_mgr_service;
+    char   *tls_tkt_cipher;
+    int     tls_daemon_rand_bytes;
+    int     tls_append_def_CA;
+    int     tls_preempt_clist;
+    int     tls_multi_wildcard;
+    int     tls_fast_shutdown;
+} TLS_CLIENT_PARAMS;
+
+#define TLS_PROXY_CLIENT_PARAMS(params, a1, a2, a3, a4, a5, a6, a7, a8, \
+    a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) \
+    (((params)->a1), ((params)->a2), ((params)->a3), \
+    ((params)->a4), ((params)->a5), ((params)->a6), ((params)->a7), \
+    ((params)->a8), ((params)->a9), ((params)->a10), ((params)->a11), \
+    ((params)->a12), ((params)->a13), ((params)->a14), ((params)->a15), \
+    ((params)->a16), ((params)->a17), ((params)->a18), ((params)->a19))
+
+extern TLS_CLIENT_PARAMS *tls_proxy_client_param_from_config(TLS_CLIENT_PARAMS *);
+extern char *tls_proxy_client_param_serialize(ATTR_PRINT_COMMON_FN, VSTRING *, const TLS_CLIENT_PARAMS *);
+extern TLS_CLIENT_PARAMS *tls_proxy_client_param_from_string(ATTR_SCAN_COMMON_FN, VSTRING *);
+extern int tls_proxy_client_param_print(ATTR_PRINT_COMMON_FN, VSTREAM *, int, const void *);
+extern void tls_proxy_client_param_free(TLS_CLIENT_PARAMS *);
+extern int tls_proxy_client_param_scan(ATTR_SCAN_COMMON_FN, VSTREAM *, int, void *);
+
+#endif                                 /* USE_TLS */
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*
+/*     Wietse Venema
+/*     Google, Inc.
+/*     111 8th Avenue
+/*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif
diff --git a/postfix/src/tls/tls_proxy_client_param_proto_test.c b/postfix/src/tls/tls_proxy_client_param_proto_test.c
new file mode 100644 (file)
index 0000000..190800b
--- /dev/null
@@ -0,0 +1,286 @@
+/*++
+/* NAME
+/*     tls_proxy_client_param_proto_test 1t
+/* SUMMARY
+/*     tls_proxy_client_param_proto unit test
+/* SYNOPSIS
+/*     ./tls_proxy_client_param_proto_test
+/* DESCRIPTION
+/*     tls_proxy_client_param_proto_test runs and logs each configured test, reports if
+/*     a test is a PASS or FAIL, and returns an exit status of zero if
+/*     all tests are a PASS.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+
+ /*
+  * Utility library.
+  */
+
+ /*
+  * Global library.
+  */
+#include <mail_params.h>
+
+ /*
+  * TLS library.
+  */
+#include <tls_proxy_client_param_proto.h>
+#include <tls_proxy_attr.h>
+
+ /*
+  * Test libraries.
+  */
+#include <ptest.h>
+#include <make_attr.h>
+#include <match_attr.h>
+
+ /*
+  * Test structure.
+  */
+typedef struct PTEST_CASE {
+    const char *testname;
+    void    (*action) (PTEST_CTX *, const struct PTEST_CASE *);
+} PTEST_CASE;
+
+#ifdef USE_TLS
+
+ /*
+  * Scaffolding: configuration parameters.
+  */
+char   *var_tls_cnf_file;
+char   *var_tls_cnf_name;
+char   *var_tls_high_clist;
+char   *var_tls_medium_clist;
+char   *var_tls_null_clist;
+char   *var_tls_eecdh_auto;
+char   *var_tls_eecdh_strong;
+char   *var_tls_eecdh_ultra;
+char   *var_tls_ffdhe_auto;
+char   *var_tls_bug_tweaks;
+char   *var_tls_ssl_options;
+char   *var_tls_dane_digests;
+char   *var_tls_mgr_service;
+char   *var_tls_tkt_cipher;
+int     var_tls_daemon_rand_bytes;
+bool    var_tls_append_def_CA;
+bool    var_tls_preempt_clist;
+bool    var_tls_multi_wildcard;
+bool    tls_fast_shutdown;
+
+static void init_global_params(void)
+{
+    var_tls_cnf_file = DEF_TLS_CNF_FILE;
+    var_tls_cnf_name = DEF_TLS_CNF_NAME;
+    var_tls_high_clist = DEF_TLS_HIGH_CLIST;
+    var_tls_medium_clist = DEF_TLS_MEDIUM_CLIST;
+    var_tls_null_clist = DEF_TLS_NULL_CLIST;
+    var_tls_eecdh_auto = DEF_TLS_EECDH_AUTO;
+    var_tls_eecdh_strong = DEF_TLS_EECDH_STRONG;
+    var_tls_eecdh_ultra = DEF_TLS_EECDH_ULTRA;
+    var_tls_ffdhe_auto = DEF_TLS_FFDHE_AUTO;
+    var_tls_bug_tweaks = DEF_TLS_BUG_TWEAKS;
+    var_tls_dane_digests = DEF_TLS_DANE_DIGESTS;
+    var_tls_ssl_options = DEF_TLS_SSL_OPTIONS;
+    var_tls_mgr_service = DEF_TLS_MGR_SERVICE;
+    var_tls_tkt_cipher = DEF_TLS_TKT_CIPHER;
+    var_tls_daemon_rand_bytes = DEF_TLS_DAEMON_RAND_BYTES;
+    var_tls_append_def_CA = DEF_TLS_APPEND_DEF_CA;
+    var_tls_preempt_clist = DEF_TLS_PREEMPT_CLIST;
+    var_tls_multi_wildcard = DEF_TLS_MULTI_WILDCARD;
+    var_tls_fast_shutdown = DEF_TLS_FAST_SHUTDOWN;
+}
+
+static void setup_reference_unserialized_params(TLS_CLIENT_PARAMS *params)
+{
+    TLS_PROXY_CLIENT_PARAMS(params,
+                           tls_cnf_file = DEF_TLS_CNF_FILE,
+                           tls_cnf_name = DEF_TLS_CNF_NAME,
+                           tls_high_clist = DEF_TLS_HIGH_CLIST,
+                           tls_medium_clist = DEF_TLS_MEDIUM_CLIST,
+                           tls_null_clist = DEF_TLS_NULL_CLIST,
+                           tls_eecdh_auto = DEF_TLS_EECDH_AUTO,
+                           tls_eecdh_strong = DEF_TLS_EECDH_STRONG,
+                           tls_eecdh_ultra = DEF_TLS_EECDH_ULTRA,
+                           tls_ffdhe_auto = DEF_TLS_FFDHE_AUTO,
+                           tls_bug_tweaks = DEF_TLS_BUG_TWEAKS,
+                           tls_ssl_options = DEF_TLS_SSL_OPTIONS,
+                           tls_dane_digests = DEF_TLS_DANE_DIGESTS,
+                           tls_mgr_service = DEF_TLS_MGR_SERVICE,
+                           tls_tkt_cipher = DEF_TLS_TKT_CIPHER,
+                           tls_daemon_rand_bytes
+                           = DEF_TLS_DAEMON_RAND_BYTES,
+                           tls_append_def_CA = DEF_TLS_APPEND_DEF_CA,
+                           tls_preempt_clist = DEF_TLS_PREEMPT_CLIST,
+                           tls_multi_wildcard = DEF_TLS_MULTI_WILDCARD,
+                           tls_fast_shutdown = DEF_TLS_FAST_SHUTDOWN);
+}
+
+static VSTRING *setup_reference_serialized_params(TLS_CLIENT_PARAMS *params)
+{
+    return (make_attr(attr_vprint, ATTR_FLAG_NONE,
+                     SEND_ATTR_STR(TLS_ATTR_CNF_FILE, params->tls_cnf_file),
+                     SEND_ATTR_STR(TLS_ATTR_CNF_NAME, params->tls_cnf_name),
+                     SEND_ATTR_STR(VAR_TLS_HIGH_CLIST,
+                                   params->tls_high_clist),
+                     SEND_ATTR_STR(VAR_TLS_MEDIUM_CLIST,
+                                   params->tls_medium_clist),
+                     SEND_ATTR_STR(VAR_TLS_NULL_CLIST,
+                                   params->tls_null_clist),
+                     SEND_ATTR_STR(VAR_TLS_EECDH_AUTO,
+                                   params->tls_eecdh_auto),
+                     SEND_ATTR_STR(VAR_TLS_EECDH_STRONG,
+                                   params->tls_eecdh_strong),
+                     SEND_ATTR_STR(VAR_TLS_EECDH_ULTRA,
+                                   params->tls_eecdh_ultra),
+                     SEND_ATTR_STR(VAR_TLS_FFDHE_AUTO,
+                                   params->tls_ffdhe_auto),
+                     SEND_ATTR_STR(VAR_TLS_BUG_TWEAKS,
+                                   params->tls_bug_tweaks),
+                     SEND_ATTR_STR(VAR_TLS_SSL_OPTIONS,
+                                   params->tls_ssl_options),
+                     SEND_ATTR_STR(VAR_TLS_DANE_DIGESTS,
+                                   params->tls_dane_digests),
+                     SEND_ATTR_STR(VAR_TLS_MGR_SERVICE,
+                                   params->tls_mgr_service),
+                     SEND_ATTR_STR(VAR_TLS_TKT_CIPHER,
+                                   params->tls_tkt_cipher),
+                     SEND_ATTR_INT(VAR_TLS_DAEMON_RAND_BYTES,
+                                   params->tls_daemon_rand_bytes),
+                     SEND_ATTR_INT(VAR_TLS_APPEND_DEF_CA,
+                                    params->tls_append_def_CA),
+                     SEND_ATTR_INT(VAR_TLS_PREEMPT_CLIST,
+                                    params->tls_preempt_clist),
+                     SEND_ATTR_INT(VAR_TLS_MULTI_WILDCARD,
+                                    params->tls_multi_wildcard),
+                     SEND_ATTR_INT(VAR_TLS_FAST_SHUTDOWN,
+                                    params->tls_fast_shutdown),
+                     ATTR_TYPE_END));
+}
+
+#endif
+
+/* Note: this also tests tls_proxy_client_param_print() */
+
+static void test_tls_proxy_client_param_serialize(PTEST_CTX *t,
+                                           const struct PTEST_CASE *unused)
+{
+#ifdef USE_TLS
+    TLS_CLIENT_PARAMS ref_unserialized_params;
+    VSTRING *got_serialized_params;
+    VSTRING *ref_serialized_params;
+
+    init_global_params();
+
+    setup_reference_unserialized_params(&ref_unserialized_params);
+
+    ref_serialized_params = setup_reference_serialized_params(
+                                                 &ref_unserialized_params);
+
+    tls_proxy_client_param_serialize(attr_print,
+                                got_serialized_params = vstring_alloc(100),
+                                  (const void *) &ref_unserialized_params);
+
+    (void) eq_attr(t, "tls_proxy_client_param_serialize",
+                  got_serialized_params, ref_serialized_params);
+#else
+    ptest_skip(t);
+#endif
+}
+
+static void test_tls_proxy_client_param_from_config(PTEST_CTX *t,
+                                           const struct PTEST_CASE *unused)
+{
+#ifdef USE_TLS
+    TLS_CLIENT_PARAMS ref_unserialized_params;
+    TLS_CLIENT_PARAMS got_client_params;
+    TLS_CLIENT_PARAMS *p;
+    VSTRING *want_client_params_serialized;
+    VSTRING *got_client_params_serialized;
+
+    init_global_params();
+
+    setup_reference_unserialized_params(&ref_unserialized_params);
+
+    tls_proxy_client_param_serialize(attr_print,
+                        want_client_params_serialized = vstring_alloc(100),
+                                    &ref_unserialized_params);
+
+    init_global_params();
+
+    p = tls_proxy_client_param_from_config(&got_client_params);
+    if (p != &got_client_params)
+       ptest_fatal(t, "unexpected tls_proxy_client_param_from_config() result: got %p, and %p",
+                   (void *) p, (void *) &got_client_params);
+
+    tls_proxy_client_param_serialize(attr_print,
+                         got_client_params_serialized = vstring_alloc(100),
+                                    &got_client_params);
+
+    (void) eq_attr(t, "tls_proxy_client_param_from_config",
+              got_client_params_serialized, want_client_params_serialized);
+
+    vstring_free(want_client_params_serialized);
+    vstring_free(got_client_params_serialized);
+#else
+    ptest_skip(t);
+#endif
+}
+
+/* Note: this also tests tls_proxy_client_param_scan() */
+
+static void test_tls_proxy_client_param_from_string(PTEST_CTX *t,
+                                           const struct PTEST_CASE *unused)
+{
+#ifdef USE_TLS
+    TLS_CLIENT_PARAMS ref_unserialized_params;
+    VSTRING *ref_serialized_params;
+    VSTRING *got_serialized_params;
+    TLS_CLIENT_PARAMS *deserialized_params;
+
+    init_global_params();
+
+    setup_reference_unserialized_params(&ref_unserialized_params);
+
+    ref_serialized_params = setup_reference_serialized_params(
+                                                 &ref_unserialized_params);
+
+    deserialized_params = tls_proxy_client_param_from_string(attr_scan,
+                                                    ref_serialized_params);
+    if (deserialized_params == 0)
+       ptest_fatal(t, "tls_proxy_client_param_from_string failed");
+
+    tls_proxy_client_param_serialize(attr_print,
+                                got_serialized_params = vstring_alloc(100),
+                                    deserialized_params);
+
+    eq_attr(t, "tls_proxy_client_param_from_string",
+           got_serialized_params, ref_serialized_params);
+
+    vstring_free(ref_serialized_params);
+    vstring_free(got_serialized_params);
+#else
+    ptest_skip(t);
+#endif
+}
+
+ /*
+  * The list of test cases.
+  */
+static const PTEST_CASE ptestcases[] = {
+    "test_tls_proxy_client_param_serialize", test_tls_proxy_client_param_serialize,
+    "test_tls_proxy_client_param_from_config", test_tls_proxy_client_param_from_config,
+    "test_tls_proxy_client_param_from_string", test_tls_proxy_client_param_from_string,
+};
+
+#include <ptest_main.h>
diff --git a/postfix/src/tls/tls_proxy_client_print.c b/postfix/src/tls/tls_proxy_client_print.c
deleted file mode 100644 (file)
index f07aafb..0000000
+++ /dev/null
@@ -1,356 +0,0 @@
-/*++
-/* NAME
-/*     tls_proxy_client_print 3
-/* SUMMARY
-/*     write TLS_CLIENT_XXX structures to stream
-/* SYNOPSIS
-/*     #include <tls_proxy.h>
-/*
-/*     int     tls_proxy_client_param_print(print_fn, stream, flags, ptr)
-/*     ATTR_PRINT_COMMON_FN print_fn;
-/*     VSTREAM *stream;
-/*     int     flags;
-/*     const void *ptr;
-/*
-/*     int     tls_proxy_client_init_print(print_fn, stream, flags, ptr)
-/*     ATTR_PRINT_COMMON_FN print_fn;
-/*     VSTREAM *stream;
-/*     int     flags;
-/*     const void *ptr;
-/*
-/*     int     tls_proxy_client_start_print(print_fn, stream, flags, ptr)
-/*     ATTR_PRINT_COMMON_FN print_fn;
-/*     VSTREAM *stream;
-/*     int     flags;
-/*     const void *ptr;
-/* DESCRIPTION
-/*     tls_proxy_client_param_print() writes a TLS_CLIENT_PARAMS structure to
-/*     the named stream using the specified attribute print routine.
-/*     tls_proxy_client_param_print() is meant to be passed as a call-back to
-/*     attr_print(), thusly:
-/*
-/*     SEND_ATTR_FUNC(tls_proxy_client_param_print, (const void *) param), ...
-/*
-/*     tls_proxy_client_init_print() writes a full TLS_CLIENT_INIT_PROPS
-/*     structure to the named stream using the specified attribute
-/*     print routine. tls_proxy_client_init_print() is meant to
-/*     be passed as a call-back to attr_print(), thusly:
-/*
-/*     SEND_ATTR_FUNC(tls_proxy_client_init_print, (const void *) init_props), ...
-/*
-/*     tls_proxy_client_start_print() writes a TLS_CLIENT_START_PROPS
-/*     structure, without stream or file descriptor members, to
-/*     the named stream using the specified attribute print routine.
-/*     tls_proxy_client_start_print() is meant to be passed as a
-/*     call-back to attr_print(), thusly:
-/*
-/*     SEND_ATTR_FUNC(tls_proxy_client_start_print, (const void *) start_props), ...
-/* DIAGNOSTICS
-/*     Fatal: out of memory.
-/* LICENSE
-/* .ad
-/* .fi
-/*     The Secure Mailer license must be distributed with this software.
-/* AUTHOR(S)
-/*     Wietse Venema
-/*     Google, Inc.
-/*     111 8th Avenue
-/*     New York, NY 10011, USA
-/*--*/
-
-#ifdef USE_TLS
-
-/* System library. */
-
-#include <sys_defs.h>
-
-/* Utility library */
-
-#include <argv_attr.h>
-#include <attr.h>
-#include <msg.h>
-
-/* Global library. */
-
-#include <mail_params.h>
-
-/* TLS library. */
-
-#include <tls.h>
-#include <tls_proxy.h>
-
-#ifdef USE_TLSRPT
-#define TLSRPT_WRAPPER_INTERNAL
-#include <tlsrpt_wrapper.h>
-#endif
-
-#define STR(x) vstring_str(x)
-#define LEN(x) VSTRING_LEN(x)
-
-/* tls_proxy_client_param_print - send TLS_CLIENT_PARAMS over stream */
-
-int     tls_proxy_client_param_print(ATTR_PRINT_COMMON_FN print_fn, VSTREAM *fp,
-                                            int flags, const void *ptr)
-{
-    const TLS_CLIENT_PARAMS *params = (const TLS_CLIENT_PARAMS *) ptr;
-    int     ret;
-
-    if (msg_verbose)
-       msg_info("begin tls_proxy_client_param_print");
-
-    ret = print_fn(fp, flags | ATTR_FLAG_MORE,
-                  SEND_ATTR_STR(TLS_ATTR_CNF_FILE, params->tls_cnf_file),
-                  SEND_ATTR_STR(TLS_ATTR_CNF_NAME, params->tls_cnf_name),
-                  SEND_ATTR_STR(VAR_TLS_HIGH_CLIST, params->tls_high_clist),
-                  SEND_ATTR_STR(VAR_TLS_MEDIUM_CLIST,
-                                params->tls_medium_clist),
-                  SEND_ATTR_STR(VAR_TLS_NULL_CLIST, params->tls_null_clist),
-                  SEND_ATTR_STR(VAR_TLS_EECDH_AUTO, params->tls_eecdh_auto),
-                  SEND_ATTR_STR(VAR_TLS_EECDH_STRONG,
-                                params->tls_eecdh_strong),
-                  SEND_ATTR_STR(VAR_TLS_EECDH_ULTRA,
-                                params->tls_eecdh_ultra),
-                  SEND_ATTR_STR(VAR_TLS_FFDHE_AUTO, params->tls_ffdhe_auto),
-                  SEND_ATTR_STR(VAR_TLS_BUG_TWEAKS, params->tls_bug_tweaks),
-                  SEND_ATTR_STR(VAR_TLS_SSL_OPTIONS,
-                                params->tls_ssl_options),
-                  SEND_ATTR_STR(VAR_TLS_DANE_DIGESTS,
-                                params->tls_dane_digests),
-                  SEND_ATTR_STR(VAR_TLS_MGR_SERVICE,
-                                params->tls_mgr_service),
-                  SEND_ATTR_STR(VAR_TLS_TKT_CIPHER, params->tls_tkt_cipher),
-                  SEND_ATTR_INT(VAR_TLS_DAEMON_RAND_BYTES,
-                                params->tls_daemon_rand_bytes),
-                  SEND_ATTR_INT(VAR_TLS_APPEND_DEF_CA,
-                                params->tls_append_def_CA),
-                  SEND_ATTR_INT(VAR_TLS_PREEMPT_CLIST,
-                                params->tls_preempt_clist),
-                  SEND_ATTR_INT(VAR_TLS_MULTI_WILDCARD,
-                                params->tls_multi_wildcard),
-                  ATTR_TYPE_END);
-    /* Do not flush the stream. */
-    if (msg_verbose)
-       msg_info("tls_proxy_client_param_print ret=%d", ret);
-    return (ret);
-}
-
-/* tls_proxy_client_init_print - send TLS_CLIENT_INIT_PROPS over stream */
-
-int     tls_proxy_client_init_print(ATTR_PRINT_COMMON_FN print_fn, VSTREAM *fp,
-                                           int flags, const void *ptr)
-{
-    const TLS_CLIENT_INIT_PROPS *props = (const TLS_CLIENT_INIT_PROPS *) ptr;
-    int     ret;
-
-    if (msg_verbose)
-       msg_info("begin tls_proxy_client_init_print");
-
-#define STRING_OR_EMPTY(s) ((s) ? (s) : "")
-
-    ret = print_fn(fp, flags | ATTR_FLAG_MORE,
-                  SEND_ATTR_STR(TLS_ATTR_LOG_PARAM,
-                                STRING_OR_EMPTY(props->log_param)),
-                  SEND_ATTR_STR(TLS_ATTR_LOG_LEVEL,
-                                STRING_OR_EMPTY(props->log_level)),
-                  SEND_ATTR_INT(TLS_ATTR_VERIFYDEPTH, props->verifydepth),
-                  SEND_ATTR_STR(TLS_ATTR_CACHE_TYPE,
-                                STRING_OR_EMPTY(props->cache_type)),
-                  SEND_ATTR_STR(TLS_ATTR_CHAIN_FILES,
-                                STRING_OR_EMPTY(props->chain_files)),
-                  SEND_ATTR_STR(TLS_ATTR_CERT_FILE,
-                                STRING_OR_EMPTY(props->cert_file)),
-                  SEND_ATTR_STR(TLS_ATTR_KEY_FILE,
-                                STRING_OR_EMPTY(props->key_file)),
-                  SEND_ATTR_STR(TLS_ATTR_DCERT_FILE,
-                                STRING_OR_EMPTY(props->dcert_file)),
-                  SEND_ATTR_STR(TLS_ATTR_DKEY_FILE,
-                                STRING_OR_EMPTY(props->dkey_file)),
-                  SEND_ATTR_STR(TLS_ATTR_ECCERT_FILE,
-                                STRING_OR_EMPTY(props->eccert_file)),
-                  SEND_ATTR_STR(TLS_ATTR_ECKEY_FILE,
-                                STRING_OR_EMPTY(props->eckey_file)),
-                  SEND_ATTR_STR(TLS_ATTR_CAFILE,
-                                STRING_OR_EMPTY(props->CAfile)),
-                  SEND_ATTR_STR(TLS_ATTR_CAPATH,
-                                STRING_OR_EMPTY(props->CApath)),
-                  SEND_ATTR_STR(TLS_ATTR_MDALG,
-                                STRING_OR_EMPTY(props->mdalg)),
-                  ATTR_TYPE_END);
-    /* Do not flush the stream. */
-    if (msg_verbose)
-       msg_info("tls_proxy_client_init_print ret=%d", ret);
-    return (ret);
-}
-
-/* tls_proxy_client_tlsa_print - send TLS_TLSA over stream */
-
-static int tls_proxy_client_tlsa_print(ATTR_PRINT_COMMON_FN print_fn,
-                                   VSTREAM *fp, int flags, const void *ptr)
-{
-    const TLS_TLSA *head = (const TLS_TLSA *) ptr;
-    const TLS_TLSA *tp;
-    int     count;
-    int     ret;
-
-    for (tp = head, count = 0; tp != 0; tp = tp->next)
-       ++count;
-    if (msg_verbose)
-       msg_info("tls_proxy_client_tlsa_print count=%d", count);
-
-    ret = print_fn(fp, flags | ATTR_FLAG_MORE,
-                  SEND_ATTR_INT(TLS_ATTR_COUNT, count),
-                  ATTR_TYPE_END);
-
-    for (tp = head; ret == 0 && tp != 0; tp = tp->next)
-       ret = print_fn(fp, flags | ATTR_FLAG_MORE,
-                      SEND_ATTR_INT(TLS_ATTR_USAGE, tp->usage),
-                      SEND_ATTR_INT(TLS_ATTR_SELECTOR, tp->selector),
-                      SEND_ATTR_INT(TLS_ATTR_MTYPE, tp->mtype),
-                      SEND_ATTR_DATA(TLS_ATTR_DATA, tp->length, tp->data),
-                      ATTR_TYPE_END);
-
-    /* Do not flush the stream. */
-    if (msg_verbose)
-       msg_info("tls_proxy_client_tlsa_print ret=%d", count);
-    return (ret);
-}
-
-/* tls_proxy_client_dane_print - send TLS_DANE over stream */
-
-static int tls_proxy_client_dane_print(ATTR_PRINT_COMMON_FN print_fn,
-                                   VSTREAM *fp, int flags, const void *ptr)
-{
-    const TLS_DANE *dane = (const TLS_DANE *) ptr;
-    int     ret;
-
-    ret = print_fn(fp, flags | ATTR_FLAG_MORE,
-                  SEND_ATTR_INT(TLS_ATTR_DANE, dane != 0),
-                  ATTR_TYPE_END);
-    if (msg_verbose)
-       msg_info("tls_proxy_client_dane_print dane=%d", dane != 0);
-
-    if (ret == 0 && dane != 0) {
-       /* Send the base_domain and RRs, we don't need the other fields */
-       ret = print_fn(fp, flags | ATTR_FLAG_MORE,
-                      SEND_ATTR_STR(TLS_ATTR_DOMAIN,
-                                    STRING_OR_EMPTY(dane->base_domain)),
-                      SEND_ATTR_FUNC(tls_proxy_client_tlsa_print,
-                                     (const void *) dane->tlsa),
-                      ATTR_TYPE_END);
-    }
-    /* Do not flush the stream. */
-    if (msg_verbose)
-       msg_info("tls_proxy_client_dane_print ret=%d", ret);
-    return (ret);
-}
-
-#ifdef USE_TLSRPT
-
-/* tls_proxy_client_tlsrpt_print - send TLSRPT_WRAPPER over stream */
-
-static int tls_proxy_client_tlsrpt_print(ATTR_PRINT_COMMON_FN print_fn,
-                                   VSTREAM *fp, int flags, const void *ptr)
-{
-    const TLSRPT_WRAPPER *trw = (const TLSRPT_WRAPPER *) ptr;
-    int     have_trw = trw != 0;
-    int     ret;
-
-    ret = print_fn(fp, flags | ATTR_FLAG_MORE,
-                  SEND_ATTR_INT(TLS_ATTR_TLSRPT, have_trw),
-                  ATTR_TYPE_END);
-    if (msg_verbose)
-       msg_info("tls_proxy_client_tlsrpt_print have_trw=%d", have_trw);
-
-    if (ret == 0 && have_trw) {
-       ret = print_fn(fp, flags | ATTR_FLAG_MORE,
-                      SEND_ATTR_STR(TRW_RPT_SOCKET_NAME,
-                                    STRING_OR_EMPTY(trw->rpt_socket_name)),
-                      SEND_ATTR_STR(TRW_RPT_POLICY_DOMAIN,
-                                  STRING_OR_EMPTY(trw->rpt_policy_domain)),
-                      SEND_ATTR_STR(TRW_RPT_POLICY_STRING,
-                                  STRING_OR_EMPTY(trw->rpt_policy_string)),
-                      SEND_ATTR_INT(TRW_TLS_POLICY_TYPE,
-                                    (int) trw->tls_policy_type),
-                      SEND_ATTR_FUNC(argv_attr_print,
-                                   (const void *) trw->tls_policy_strings),
-                      SEND_ATTR_STR(TRW_TLS_POLICY_DOMAIN,
-                                  STRING_OR_EMPTY(trw->tls_policy_domain)),
-                      SEND_ATTR_FUNC(argv_attr_print,
-                                     (const void *) trw->mx_host_patterns),
-                      SEND_ATTR_STR(TRW_SRC_MTA_ADDR,
-                                    STRING_OR_EMPTY(trw->snd_mta_addr)),
-                      SEND_ATTR_STR(TRW_DST_MTA_NAME,
-                                    STRING_OR_EMPTY(trw->rcv_mta_name)),
-                      SEND_ATTR_STR(TRW_DST_MTA_ADDR,
-                                    STRING_OR_EMPTY(trw->rcv_mta_addr)),
-                      SEND_ATTR_STR(TRW_DST_MTA_EHLO,
-                                    STRING_OR_EMPTY(trw->rcv_mta_ehlo)),
-                      SEND_ATTR_INT(TRW_SKIP_REUSED_HS,
-                                    trw->skip_reused_hs),
-                      SEND_ATTR_INT(TRW_FLAGS,
-                                    trw->flags),
-                      ATTR_TYPE_END);
-    }
-    /* Do not flush the stream. */
-    if (msg_verbose)
-       msg_info("tls_proxy_client_tlsrpt_print ret=%d", ret);
-    return (ret);
-}
-
-#endif
-
-/* tls_proxy_client_start_print - send TLS_CLIENT_START_PROPS over stream */
-
-int     tls_proxy_client_start_print(ATTR_PRINT_COMMON_FN print_fn,
-                                   VSTREAM *fp, int flags, const void *ptr)
-{
-    const TLS_CLIENT_START_PROPS *props = (const TLS_CLIENT_START_PROPS *) ptr;
-    int     ret;
-
-    if (msg_verbose)
-       msg_info("begin tls_proxy_client_start_print");
-
-#define STRING_OR_EMPTY(s) ((s) ? (s) : "")
-
-    ret = print_fn(fp, flags | ATTR_FLAG_MORE,
-                  SEND_ATTR_INT(TLS_ATTR_TIMEOUT, props->timeout),
-                  SEND_ATTR_INT(TLS_ATTR_ENABLE_RPK, props->enable_rpk),
-                  SEND_ATTR_INT(TLS_ATTR_TLS_LEVEL, props->tls_level),
-                  SEND_ATTR_STR(TLS_ATTR_NEXTHOP,
-                                STRING_OR_EMPTY(props->nexthop)),
-                  SEND_ATTR_STR(TLS_ATTR_HOST,
-                                STRING_OR_EMPTY(props->host)),
-                  SEND_ATTR_STR(TLS_ATTR_NAMADDR,
-                                STRING_OR_EMPTY(props->namaddr)),
-                  SEND_ATTR_STR(TLS_ATTR_SNI,
-                                STRING_OR_EMPTY(props->sni)),
-                  SEND_ATTR_STR(TLS_ATTR_SERVERID,
-                                STRING_OR_EMPTY(props->serverid)),
-                  SEND_ATTR_STR(TLS_ATTR_HELO,
-                                STRING_OR_EMPTY(props->helo)),
-                  SEND_ATTR_STR(TLS_ATTR_PROTOCOLS,
-                                STRING_OR_EMPTY(props->protocols)),
-                  SEND_ATTR_STR(TLS_ATTR_CIPHER_GRADE,
-                                STRING_OR_EMPTY(props->cipher_grade)),
-                  SEND_ATTR_STR(TLS_ATTR_CIPHER_EXCLUSIONS,
-                                STRING_OR_EMPTY(props->cipher_exclusions)),
-                  SEND_ATTR_FUNC(argv_attr_print,
-                                 (const void *) props->matchargv),
-                  SEND_ATTR_STR(TLS_ATTR_MDALG,
-                                STRING_OR_EMPTY(props->mdalg)),
-                  SEND_ATTR_FUNC(tls_proxy_client_dane_print,
-                                 (const void *) props->dane),
-#ifdef USE_TLSRPT
-                  SEND_ATTR_FUNC(tls_proxy_client_tlsrpt_print,
-                                 (const void *) props->tlsrpt),
-#endif
-                  SEND_ATTR_STR(TLS_ATTR_FFAIL_TYPE,
-                                STRING_OR_EMPTY(props->ffail_type)),
-                  ATTR_TYPE_END);
-    /* Do not flush the stream. */
-    if (msg_verbose)
-       msg_info("tls_proxy_client_start_print ret=%d", ret);
-    return (ret);
-}
-
-#endif
similarity index 54%
rename from postfix/src/tls/tls_proxy_client_scan.c
rename to postfix/src/tls/tls_proxy_client_start_proto.c
index f70b42744161694ba61a3bdf8d6116c256da6264..5e1bc913bb36f926e15cde33102795aa37cf7073 100644 (file)
@@ -1,28 +1,16 @@
 /*++
 /* NAME
-/*     tls_proxy_client_scan 3
+/*     tls_proxy_client_start_proto 3
 /* SUMMARY
-/*     read TLS_CLIENT_XXX structures from stream
+/*     Support for TLS_CLIENT_START structures
 /* SYNOPSIS
-/*     #include <tls_proxy.h>
+/*     #include <tls_proxy_client_start_proto.h>
 /*
-/*     int     tls_proxy_client_param_scan(scan_fn, stream, flags, ptr)
-/*     ATTR_SCAN_COMMON_FN scan_fn;
+/*     int     tls_proxy_client_start_print(print_fn, stream, flags, ptr)
+/*     ATTR_PRINT_COMMON_FN print_fn;
 /*     VSTREAM *stream;
 /*     int     flags;
-/*     void    *ptr;
-/*
-/*     void    tls_proxy_client_param_free(params)
-/*     TLS_CLIENT_PARAMS *params;
-/*
-/*     int     tls_proxy_client_init_scan(scan_fn, stream, flags, ptr)
-/*     ATTR_SCAN_COMMON_FN scan_fn;
-/*     VSTREAM *stream;
-/*     int     flags;
-/*     void    *ptr;
-/*
-/*     void    tls_proxy_client_init_free(init_props)
-/*     TLS_CLIENT_INIT_PROPS *init_props;
+/*     const void *ptr;
 /*
 /*     int     tls_proxy_client_start_scan(scan_fn, stream, flags, ptr)
 /*     ATTR_SCAN_COMMON_FN scan_fn;
 /*     void    tls_proxy_client_start_free(start_props)
 /*     TLS_CLIENT_START_PROPS *start_props;
 /* DESCRIPTION
-/*     tls_proxy_client_param_scan() reads a TLS_CLIENT_PARAMS structure from
-/*     the named stream using the specified attribute scan routine.
-/*     tls_proxy_client_param_scan() is meant to be passed as a call-back
-/*     function to attr_scan(), as shown below.
+/*     tls_proxy_client_start_print() writes a TLS_CLIENT_START_PROPS
+/*     structure, without stream or file descriptor members, to
+/*     the named stream using the specified attribute print routine.
+/*     tls_proxy_client_start_print() is meant to be passed as a
+/*     call-back to attr_print(), thusly:
 /*
-/*     tls_proxy_client_param_free() destroys a TLS_CLIENT_PARAMS structure
-/*     that was created by tls_proxy_client_param_scan().
-/*
-/*     TLS_CLIENT_PARAMS *param = 0;
-/*     ...
-/*     ... RECV_ATTR_FUNC(tls_proxy_client_param_scan, (void *) &param)
-/*     ...
-/*     if (param != 0)
-/*         tls_proxy_client_param_free(param);
-/*
-/*     tls_proxy_client_init_scan() reads a full TLS_CLIENT_INIT_PROPS
-/*     structure from the named stream using the specified attribute
-/*     scan routine. tls_proxy_client_init_scan() is meant to be passed
-/*     as a call-back function to attr_scan(), as shown below.
-/*
-/*     tls_proxy_client_init_free() destroys a TLS_CLIENT_INIT_PROPS
-/*     structure that was created by tls_proxy_client_init_scan().
-/*
-/*     TLS_CLIENT_INIT_PROPS *init_props = 0;
-/*     ...
-/*     ... RECV_ATTR_FUNC(tls_proxy_client_init_scan, (void *) &init_props)
-/*     ...
-/*     if (init_props != 0)
-/*         tls_proxy_client_init_free(init_props);
+/*     SEND_ATTR_FUNC(tls_proxy_client_start_print, (const void *) start_props), ...
 /*
 /*     tls_proxy_client_start_scan() reads a TLS_CLIENT_START_PROPS
 /*     structure, without the stream of file descriptor members,
@@ -89,6 +55,9 @@
 /*     Google, Inc.
 /*     111 8th Avenue
 /*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 #ifdef USE_TLS
 #include <argv_attr.h>
 #include <attr.h>
 #include <msg.h>
-#include <vstring.h>
 
 /* Global library. */
 
 
 #define TLS_INTERNAL
 #include <tls.h>
-#include <tls_proxy.h>
+#include <tls_proxy_attr.h>
+#include <tls_proxy_client_start_proto.h>
+
 #ifdef USE_TLSRPT
 #define TLSRPT_WRAPPER_INTERNAL
 #include <tlsrpt_wrapper.h>
 #define STR(x) vstring_str(x)
 #define LEN(x) VSTRING_LEN(x)
 
-/* tls_proxy_client_param_free - destroy TLS_CLIENT_PARAMS structure */
+/* tls_proxy_client_tlsa_print - send TLS_TLSA over stream */
 
-void    tls_proxy_client_param_free(TLS_CLIENT_PARAMS *params)
+static int tls_proxy_client_tlsa_print(ATTR_PRINT_COMMON_FN print_fn,
+                                   VSTREAM *fp, int flags, const void *ptr)
 {
-    myfree(params->tls_cnf_file);
-    myfree(params->tls_cnf_name);
-    myfree(params->tls_high_clist);
-    myfree(params->tls_medium_clist);
-    myfree(params->tls_null_clist);
-    myfree(params->tls_eecdh_auto);
-    myfree(params->tls_eecdh_strong);
-    myfree(params->tls_eecdh_ultra);
-    myfree(params->tls_ffdhe_auto);
-    myfree(params->tls_bug_tweaks);
-    myfree(params->tls_ssl_options);
-    myfree(params->tls_dane_digests);
-    myfree(params->tls_mgr_service);
-    myfree(params->tls_tkt_cipher);
-    myfree((void *) params);
+    const TLS_TLSA *head = (const TLS_TLSA *) ptr;
+    const TLS_TLSA *tp;
+    int     count;
+    int     ret;
+
+    for (tp = head, count = 0; tp != 0; tp = tp->next)
+       ++count;
+    if (msg_verbose)
+       msg_info("tls_proxy_client_tlsa_print count=%d", count);
+
+    ret = print_fn(fp, flags | ATTR_FLAG_MORE,
+                  SEND_ATTR_INT(TLS_ATTR_COUNT, count),
+                  ATTR_TYPE_END);
+
+    for (tp = head; ret == 0 && tp != 0; tp = tp->next)
+       ret = print_fn(fp, flags | ATTR_FLAG_MORE,
+                      SEND_ATTR_INT(TLS_ATTR_USAGE, tp->usage),
+                      SEND_ATTR_INT(TLS_ATTR_SELECTOR, tp->selector),
+                      SEND_ATTR_INT(TLS_ATTR_MTYPE, tp->mtype),
+                      SEND_ATTR_DATA(TLS_ATTR_DATA, tp->length, tp->data),
+                      ATTR_TYPE_END);
+
+    /* Do not flush the stream. */
+    if (msg_verbose)
+       msg_info("tls_proxy_client_tlsa_print ret=%d", count);
+    return (ret);
 }
 
-/* tls_proxy_client_param_scan - receive TLS_CLIENT_PARAMS from stream */
+/* tls_proxy_client_dane_print - send TLS_DANE over stream */
 
-int     tls_proxy_client_param_scan(ATTR_SCAN_COMMON_FN scan_fn, VSTREAM *fp,
-                                           int flags, void *ptr)
+static int tls_proxy_client_dane_print(ATTR_PRINT_COMMON_FN print_fn,
+                                   VSTREAM *fp, int flags, const void *ptr)
 {
-    TLS_CLIENT_PARAMS *params
-    = (TLS_CLIENT_PARAMS *) mymalloc(sizeof(*params));
+    const TLS_DANE *dane = (const TLS_DANE *) ptr;
     int     ret;
-    VSTRING *cnf_file = vstring_alloc(25);
-    VSTRING *cnf_name = vstring_alloc(25);
-    VSTRING *tls_high_clist = vstring_alloc(25);
-    VSTRING *tls_medium_clist = vstring_alloc(25);
-    VSTRING *tls_null_clist = vstring_alloc(25);
-    VSTRING *tls_eecdh_auto = vstring_alloc(25);
-    VSTRING *tls_eecdh_strong = vstring_alloc(25);
-    VSTRING *tls_eecdh_ultra = vstring_alloc(25);
-    VSTRING *tls_ffdhe_auto = vstring_alloc(25);
-    VSTRING *tls_bug_tweaks = vstring_alloc(25);
-    VSTRING *tls_ssl_options = vstring_alloc(25);
-    VSTRING *tls_dane_digests = vstring_alloc(25);
-    VSTRING *tls_mgr_service = vstring_alloc(25);
-    VSTRING *tls_tkt_cipher = vstring_alloc(25);
 
+    ret = print_fn(fp, flags | ATTR_FLAG_MORE,
+                  SEND_ATTR_INT(TLS_ATTR_DANE, dane != 0),
+                  ATTR_TYPE_END);
     if (msg_verbose)
-       msg_info("begin tls_proxy_client_param_scan");
-
-    /*
-     * Note: memset() is not a portable way to initialize non-integer types.
-     */
-    memset(params, 0, sizeof(*params));
-    ret = scan_fn(fp, flags | ATTR_FLAG_MORE,
-                 RECV_ATTR_STR(TLS_ATTR_CNF_FILE, cnf_file),
-                 RECV_ATTR_STR(TLS_ATTR_CNF_NAME, cnf_name),
-                 RECV_ATTR_STR(VAR_TLS_HIGH_CLIST, tls_high_clist),
-                 RECV_ATTR_STR(VAR_TLS_MEDIUM_CLIST, tls_medium_clist),
-                 RECV_ATTR_STR(VAR_TLS_NULL_CLIST, tls_null_clist),
-                 RECV_ATTR_STR(VAR_TLS_EECDH_AUTO, tls_eecdh_auto),
-                 RECV_ATTR_STR(VAR_TLS_EECDH_STRONG, tls_eecdh_strong),
-                 RECV_ATTR_STR(VAR_TLS_EECDH_ULTRA, tls_eecdh_ultra),
-                 RECV_ATTR_STR(VAR_TLS_FFDHE_AUTO, tls_ffdhe_auto),
-                 RECV_ATTR_STR(VAR_TLS_BUG_TWEAKS, tls_bug_tweaks),
-                 RECV_ATTR_STR(VAR_TLS_SSL_OPTIONS, tls_ssl_options),
-                 RECV_ATTR_STR(VAR_TLS_DANE_DIGESTS, tls_dane_digests),
-                 RECV_ATTR_STR(VAR_TLS_MGR_SERVICE, tls_mgr_service),
-                 RECV_ATTR_STR(VAR_TLS_TKT_CIPHER, tls_tkt_cipher),
-                 RECV_ATTR_INT(VAR_TLS_DAEMON_RAND_BYTES,
-                               &params->tls_daemon_rand_bytes),
-                 RECV_ATTR_INT(VAR_TLS_APPEND_DEF_CA,
-                               &params->tls_append_def_CA),
-                 RECV_ATTR_INT(VAR_TLS_PREEMPT_CLIST,
-                               &params->tls_preempt_clist),
-                 RECV_ATTR_INT(VAR_TLS_MULTI_WILDCARD,
-                               &params->tls_multi_wildcard),
-                 ATTR_TYPE_END);
-    /* Always construct a well-formed structure. */
-    params->tls_cnf_file = vstring_export(cnf_file);
-    params->tls_cnf_name = vstring_export(cnf_name);
-    params->tls_high_clist = vstring_export(tls_high_clist);
-    params->tls_medium_clist = vstring_export(tls_medium_clist);
-    params->tls_null_clist = vstring_export(tls_null_clist);
-    params->tls_eecdh_auto = vstring_export(tls_eecdh_auto);
-    params->tls_eecdh_strong = vstring_export(tls_eecdh_strong);
-    params->tls_eecdh_ultra = vstring_export(tls_eecdh_ultra);
-    params->tls_ffdhe_auto = vstring_export(tls_ffdhe_auto);
-    params->tls_bug_tweaks = vstring_export(tls_bug_tweaks);
-    params->tls_ssl_options = vstring_export(tls_ssl_options);
-    params->tls_dane_digests = vstring_export(tls_dane_digests);
-    params->tls_mgr_service = vstring_export(tls_mgr_service);
-    params->tls_tkt_cipher = vstring_export(tls_tkt_cipher);
-
-    ret = (ret == 18 ? 1 : -1);
-    if (ret != 1) {
-       tls_proxy_client_param_free(params);
-       params = 0;
+       msg_info("tls_proxy_client_dane_print dane=%d", dane != 0);
+
+#define STRING_OR_EMPTY(s) ((s) ? (s) : "")
+
+    if (ret == 0 && dane != 0) {
+       /* Send the base_domain and RRs, we don't need the other fields */
+       ret = print_fn(fp, flags | ATTR_FLAG_MORE,
+                      SEND_ATTR_STR(TLS_ATTR_DOMAIN,
+                                    STRING_OR_EMPTY(dane->base_domain)),
+                      SEND_ATTR_FUNC(tls_proxy_client_tlsa_print,
+                                     (const void *) dane->tlsa),
+                      ATTR_TYPE_END);
     }
-    *(TLS_CLIENT_PARAMS **) ptr = params;
+    /* Do not flush the stream. */
     if (msg_verbose)
-       msg_info("tls_proxy_client_param_scan ret=%d", ret);
+       msg_info("tls_proxy_client_dane_print ret=%d", ret);
     return (ret);
 }
 
-/* tls_proxy_client_init_free - destroy TLS_CLIENT_INIT_PROPS structure */
+#ifdef USE_TLSRPT
+
+/* tls_proxy_client_tlsrpt_print - send TLSRPT_WRAPPER over stream */
 
-void    tls_proxy_client_init_free(TLS_CLIENT_INIT_PROPS *props)
+static int tls_proxy_client_tlsrpt_print(ATTR_PRINT_COMMON_FN print_fn,
+                                   VSTREAM *fp, int flags, const void *ptr)
 {
-    myfree((void *) props->log_param);
-    myfree((void *) props->log_level);
-    myfree((void *) props->cache_type);
-    myfree((void *) props->chain_files);
-    myfree((void *) props->cert_file);
-    myfree((void *) props->key_file);
-    myfree((void *) props->dcert_file);
-    myfree((void *) props->dkey_file);
-    myfree((void *) props->eccert_file);
-    myfree((void *) props->eckey_file);
-    myfree((void *) props->CAfile);
-    myfree((void *) props->CApath);
-    myfree((void *) props->mdalg);
-    myfree((void *) props);
+    const TLSRPT_WRAPPER *trw = (const TLSRPT_WRAPPER *) ptr;
+    int     have_trw = trw != 0;
+    int     ret;
+
+    ret = print_fn(fp, flags | ATTR_FLAG_MORE,
+                  SEND_ATTR_INT(TLS_ATTR_TLSRPT, have_trw),
+                  ATTR_TYPE_END);
+    if (msg_verbose)
+       msg_info("tls_proxy_client_tlsrpt_print have_trw=%d", have_trw);
+
+    if (ret == 0 && have_trw) {
+       ret = print_fn(fp, flags | ATTR_FLAG_MORE,
+                      SEND_ATTR_STR(TRW_RPT_SOCKET_NAME,
+                                    STRING_OR_EMPTY(trw->rpt_socket_name)),
+                      SEND_ATTR_STR(TRW_RPT_POLICY_DOMAIN,
+                                  STRING_OR_EMPTY(trw->rpt_policy_domain)),
+                      SEND_ATTR_STR(TRW_RPT_POLICY_STRING,
+                                  STRING_OR_EMPTY(trw->rpt_policy_string)),
+                      SEND_ATTR_INT(TRW_TLS_POLICY_TYPE,
+                                    (int) trw->tls_policy_type),
+                      SEND_ATTR_FUNC(argv_attr_print,
+                                   (const void *) trw->tls_policy_strings),
+                      SEND_ATTR_STR(TRW_TLS_POLICY_DOMAIN,
+                                  STRING_OR_EMPTY(trw->tls_policy_domain)),
+                      SEND_ATTR_FUNC(argv_attr_print,
+                                     (const void *) trw->mx_host_patterns),
+                      SEND_ATTR_STR(TRW_SRC_MTA_ADDR,
+                                    STRING_OR_EMPTY(trw->snd_mta_addr)),
+                      SEND_ATTR_STR(TRW_DST_MTA_NAME,
+                                    STRING_OR_EMPTY(trw->rcv_mta_name)),
+                      SEND_ATTR_STR(TRW_DST_MTA_ADDR,
+                                    STRING_OR_EMPTY(trw->rcv_mta_addr)),
+                      SEND_ATTR_STR(TRW_DST_MTA_EHLO,
+                                    STRING_OR_EMPTY(trw->rcv_mta_ehlo)),
+                      SEND_ATTR_INT(TRW_SKIP_REUSED_HS,
+                                    trw->skip_reused_hs),
+                      SEND_ATTR_INT(TRW_FLAGS,
+                                    trw->flags),
+                      ATTR_TYPE_END);
+    }
+    /* Do not flush the stream. */
+    if (msg_verbose)
+       msg_info("tls_proxy_client_tlsrpt_print ret=%d", ret);
+    return (ret);
 }
 
-/* tls_proxy_client_init_scan - receive TLS_CLIENT_INIT_PROPS from stream */
+#endif
+
+/* tls_proxy_client_start_print - send TLS_CLIENT_START_PROPS over stream */
 
-int     tls_proxy_client_init_scan(ATTR_SCAN_COMMON_FN scan_fn, VSTREAM *fp,
-                                          int flags, void *ptr)
+int     tls_proxy_client_start_print(ATTR_PRINT_COMMON_FN print_fn,
+                                   VSTREAM *fp, int flags, const void *ptr)
 {
-    TLS_CLIENT_INIT_PROPS *props
-    = (TLS_CLIENT_INIT_PROPS *) mymalloc(sizeof(*props));
+    const TLS_CLIENT_START_PROPS *props = (const TLS_CLIENT_START_PROPS *) ptr;
     int     ret;
-    VSTRING *log_param = vstring_alloc(25);
-    VSTRING *log_level = vstring_alloc(25);
-    VSTRING *cache_type = vstring_alloc(25);
-    VSTRING *chain_files = vstring_alloc(25);
-    VSTRING *cert_file = vstring_alloc(25);
-    VSTRING *key_file = vstring_alloc(25);
-    VSTRING *dcert_file = vstring_alloc(25);
-    VSTRING *dkey_file = vstring_alloc(25);
-    VSTRING *eccert_file = vstring_alloc(25);
-    VSTRING *eckey_file = vstring_alloc(25);
-    VSTRING *CAfile = vstring_alloc(25);
-    VSTRING *CApath = vstring_alloc(25);
-    VSTRING *mdalg = vstring_alloc(25);
 
     if (msg_verbose)
-       msg_info("begin tls_proxy_client_init_scan");
-
-    /*
-     * Note: memset() is not a portable way to initialize non-integer types.
-     */
-    memset(props, 0, sizeof(*props));
-    ret = scan_fn(fp, flags | ATTR_FLAG_MORE,
-                 RECV_ATTR_STR(TLS_ATTR_LOG_PARAM, log_param),
-                 RECV_ATTR_STR(TLS_ATTR_LOG_LEVEL, log_level),
-                 RECV_ATTR_INT(TLS_ATTR_VERIFYDEPTH, &props->verifydepth),
-                 RECV_ATTR_STR(TLS_ATTR_CACHE_TYPE, cache_type),
-                 RECV_ATTR_STR(TLS_ATTR_CHAIN_FILES, chain_files),
-                 RECV_ATTR_STR(TLS_ATTR_CERT_FILE, cert_file),
-                 RECV_ATTR_STR(TLS_ATTR_KEY_FILE, key_file),
-                 RECV_ATTR_STR(TLS_ATTR_DCERT_FILE, dcert_file),
-                 RECV_ATTR_STR(TLS_ATTR_DKEY_FILE, dkey_file),
-                 RECV_ATTR_STR(TLS_ATTR_ECCERT_FILE, eccert_file),
-                 RECV_ATTR_STR(TLS_ATTR_ECKEY_FILE, eckey_file),
-                 RECV_ATTR_STR(TLS_ATTR_CAFILE, CAfile),
-                 RECV_ATTR_STR(TLS_ATTR_CAPATH, CApath),
-                 RECV_ATTR_STR(TLS_ATTR_MDALG, mdalg),
-                 ATTR_TYPE_END);
-    /* Always construct a well-formed structure. */
-    props->log_param = vstring_export(log_param);
-    props->log_level = vstring_export(log_level);
-    props->cache_type = vstring_export(cache_type);
-    props->chain_files = vstring_export(chain_files);
-    props->cert_file = vstring_export(cert_file);
-    props->key_file = vstring_export(key_file);
-    props->dcert_file = vstring_export(dcert_file);
-    props->dkey_file = vstring_export(dkey_file);
-    props->eccert_file = vstring_export(eccert_file);
-    props->eckey_file = vstring_export(eckey_file);
-    props->CAfile = vstring_export(CAfile);
-    props->CApath = vstring_export(CApath);
-    props->mdalg = vstring_export(mdalg);
-    ret = (ret == 14 ? 1 : -1);
-    if (ret != 1) {
-       tls_proxy_client_init_free(props);
-       props = 0;
-    }
-    *(TLS_CLIENT_INIT_PROPS **) ptr = props;
+       msg_info("begin tls_proxy_client_start_print");
+
+#define STRING_OR_EMPTY(s) ((s) ? (s) : "")
+
+    ret = print_fn(fp, flags | ATTR_FLAG_MORE,
+                  SEND_ATTR_INT(TLS_ATTR_TIMEOUT, props->timeout),
+                  SEND_ATTR_INT(TLS_ATTR_ENABLE_RPK, props->enable_rpk),
+                  SEND_ATTR_INT(TLS_ATTR_TLS_LEVEL, props->tls_level),
+                  SEND_ATTR_STR(TLS_ATTR_NEXTHOP,
+                                STRING_OR_EMPTY(props->nexthop)),
+                  SEND_ATTR_STR(TLS_ATTR_HOST,
+                                STRING_OR_EMPTY(props->host)),
+                  SEND_ATTR_STR(TLS_ATTR_NAMADDR,
+                                STRING_OR_EMPTY(props->namaddr)),
+                  SEND_ATTR_STR(TLS_ATTR_SNI,
+                                STRING_OR_EMPTY(props->sni)),
+                  SEND_ATTR_STR(TLS_ATTR_SERVERID,
+                                STRING_OR_EMPTY(props->serverid)),
+                  SEND_ATTR_STR(TLS_ATTR_HELO,
+                                STRING_OR_EMPTY(props->helo)),
+                  SEND_ATTR_STR(TLS_ATTR_PROTOCOLS,
+                                STRING_OR_EMPTY(props->protocols)),
+                  SEND_ATTR_STR(TLS_ATTR_CIPHER_GRADE,
+                                STRING_OR_EMPTY(props->cipher_grade)),
+                  SEND_ATTR_STR(TLS_ATTR_CIPHER_EXCLUSIONS,
+                                STRING_OR_EMPTY(props->cipher_exclusions)),
+                  SEND_ATTR_FUNC(argv_attr_print,
+                                 (const void *) props->matchargv),
+                  SEND_ATTR_STR(TLS_ATTR_MDALG,
+                                STRING_OR_EMPTY(props->mdalg)),
+                  SEND_ATTR_FUNC(tls_proxy_client_dane_print,
+                                 (const void *) props->dane),
+#ifdef USE_TLSRPT
+                  SEND_ATTR_FUNC(tls_proxy_client_tlsrpt_print,
+                                 (const void *) props->tlsrpt),
+#endif
+                  SEND_ATTR_STR(TLS_ATTR_FFAIL_TYPE,
+                                STRING_OR_EMPTY(props->ffail_type)),
+                  ATTR_TYPE_END);
+    /* Do not flush the stream. */
     if (msg_verbose)
-       msg_info("tls_proxy_client_init_scan ret=%d", ret);
+       msg_info("tls_proxy_client_start_print ret=%d", ret);
     return (ret);
 }
 
diff --git a/postfix/src/tls/tls_proxy_client_start_proto.h b/postfix/src/tls/tls_proxy_client_start_proto.h
new file mode 100644 (file)
index 0000000..9965c68
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef _TLS_PROXY_CLIENT_START_PROTO_H_INCLUDED_
+#define _TLS_PROXY_CLIENT_START_PROTO_H_INCLUDED_
+
+/*++
+/* NAME
+/*     tls_proxy_client_start_proto 3h
+/* SUMMARY
+/*     TLS_CLIENT_START support
+/* SYNOPSIS
+/*     #include <tls_proxy_client_start_proto.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <vstream.h>
+#include <attr.h>
+
+ /*
+  * TLS library.
+  */
+#include <tls.h>
+
+#ifdef USE_TLS
+
+#define TLS_PROXY_CLIENT_START_PROPS(props, a1, a2, a3, a4, a5, a6, a7, a8, \
+    a9, a10, a11, a12, a13, a14, a15, a16, a17) \
+    (((props)->a1), ((props)->a2), ((props)->a3), \
+    ((props)->a4), ((props)->a5), ((props)->a6), ((props)->a7), \
+    ((props)->a8), ((props)->a9), ((props)->a10), ((props)->a11), \
+    ((props)->a12), ((props)->a13), ((props)->a14), ((props)->a15), \
+    ((props)->a16), ((props)->a17))
+
+extern int tls_proxy_client_start_print(ATTR_PRINT_COMMON_FN, VSTREAM *, int, const void *);
+extern void tls_proxy_client_start_free(TLS_CLIENT_START_PROPS *);
+extern int tls_proxy_client_start_scan(ATTR_SCAN_COMMON_FN, VSTREAM *, int, void *);
+
+#endif                                 /* USE_TLS */
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*
+/*     Wietse Venema
+/*     Google, Inc.
+/*     111 8th Avenue
+/*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif
similarity index 52%
rename from postfix/src/tls/tls_proxy_server_scan.c
rename to postfix/src/tls/tls_proxy_server_init_proto.c
index 92da66cf835c1208620dce697cace50c2fabd72f..65860dfc2532f24937cdb8119fa0e451ca406f0f 100644 (file)
@@ -1,29 +1,53 @@
 /*++
 /* NAME
-/*     tls_proxy_server_scan 3
+/*     tls_proxy_server_init_proto 3
 /* SUMMARY
-/*     read TLS_SERVER_XXX structures from stream
+/*     TLS_SERVER_XXX structure support
 /* SYNOPSIS
-/*     #include <tls_proxy.h>
+/*     #include <tls_proxy_server_init_proto.h>
 /*
-/*     int     tls_proxy_server_init_scan(scan_fn, stream, flags, ptr)
-/*     ATTR_SCAN_COMMON_FN scan_fn;
+/*     char    *tls_proxy_server_init_serialize(print_fn, buf, init_props)
+/*     ATTR_PRINT_COMMON_FN print_fn;
+/*     VSTRING *buf;
+/*     const TLS_SERVER_INIT_PROPS *init_props;
+/*
+/*     TLS_SERVER_INIT_PROPS *tls_proxy_server_init_from_string(
+/*     ATTR_SCAN_COMMON_FN scan_fn,
+/*     const VSTRING *buf)
+/*
+/*     int     tls_proxy_server_init_print(print_fn, stream, flags, ptr)
+/*     ATTR_PRINT_COMMON_FN print_fn;
 /*     VSTREAM *stream;
 /*     int     flags;
 /*     void    *ptr;
 /*
-/*     tls_proxy_server_init_free(init_props)
-/*     TLS_SERVER_INIT_PROPS *init_props;
-/*
-/*     int     tls_proxy_server_start_scan(scan_fn, stream, flags, ptr)
+/*     int     tls_proxy_server_init_scan(scan_fn, stream, flags, ptr)
 /*     ATTR_SCAN_COMMON_FN scan_fn;
 /*     VSTREAM *stream;
 /*     int     flags;
 /*     void    *ptr;
 /*
-/*     void    tls_proxy_server_start_free(start_props)
-/*     TLS_SERVER_START_PROPS *start_props;
+/*     tls_proxy_server_init_free(init_props)
+/*     TLS_SERVER_INIT_PROPS *init_props;
 /* DESCRIPTION
+/*     tls_proxy_server_init_serialize() serializes the specified object
+/*     to a memory buffer, using the specified print function (typically,
+/*     attr_print_plain). The result can be used determine whether
+/*     there are any differences between instances of the same object
+/*     type.
+/*
+/*      tls_proxy_server_init_from_string() deserializes the specified
+/*      buffer into a TLS_SERVER_INIT_PROPS object, and returns null in case
+/*      of error. The result if not null should be passed to
+/*      tls_proxy_server_init_free().
+/*
+/*     tls_proxy_server_init_print() writes a TLS_SERVER_INIT_PROPS
+/*     structure to the named stream using the specified attribute print
+/*     routine. tls_proxy_server_init_print() is meant to be passed as
+/*     a call-back to attr_print(), thusly:
+/*
+/*     ... SEND_ATTR_FUNC(tls_proxy_server_init_print, (const void *) init_props), ...
+/*
 /*     tls_proxy_server_init_scan() reads a TLS_SERVER_INIT_PROPS
 /*     structure from the named stream using the specified attribute
 /*     scan routine. tls_proxy_server_init_scan() is meant to be passed
 /*     ... RECV_ATTR_FUNC(tls_proxy_server_init_scan, (void *) &init_props)
 /*     ...
 /*     if (init_props)
-/*         tls_proxy_client_init_free(init_props);
-/*
-/*     tls_proxy_server_start_scan() reads a TLS_SERVER_START_PROPS
-/*     structure from the named stream using the specified attribute
-/*     scan routine. tls_proxy_server_start_scan() is meant to be passed
-/*     as a call-back function to attr_scan(), as shown below.
-/*
-/*     tls_proxy_server_start_free() destroys a TLS_SERVER_START_PROPS
-/*     structure that was created by tls_proxy_server_start_scan().
-/*
-/*     TLS_SERVER_START_PROPS *start_props = 0;
-/*     ...
-/*     ... RECV_ATTR_FUNC(tls_proxy_server_start_scan, (void *) &start_props)
-/*     ...
-/*     if (start_props)
-/*         tls_proxy_server_start_free(start_props);
-/* DIAGNOSTICS
-/*     Fatal: out of memory.
+/*         tls_proxy_server_init_free(init_props);
 /* LICENSE
 /* .ad
 /* .fi
@@ -64,6 +71,9 @@
 /*     Google, Inc.
 /*     111 8th Avenue
 /*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 #ifdef USE_TLS
 /* Utility library */
 
 #include <attr.h>
+#include <msg.h>
+
+/* Global library. */
+
+#include <mail_params.h>
 
 /* TLS library. */
 
 #include <tls.h>
-#include <tls_proxy.h>
+#include <tls_proxy_attr.h>
+#include <tls_proxy_server_init_proto.h>
+
+/* tls_proxy_server_init_serialize - serialize to string */
+
+char   *tls_proxy_server_init_serialize(ATTR_PRINT_COMMON_FN print_fn,
+                                               VSTRING *buf,
+                                        const TLS_SERVER_INIT_PROPS *props)
+{
+    const char myname[] = "tls_proxy_server_init_serialize";
+    VSTREAM *mp;
+
+    if ((mp = vstream_memopen(buf, O_WRONLY)) == 0
+       || print_fn(mp, ATTR_FLAG_NONE,
+                   SEND_ATTR_FUNC(tls_proxy_server_init_print,
+                                  (const void *) props),
+                   ATTR_TYPE_END) != 0
+       || vstream_fclose(mp) != 0)
+       msg_fatal("%s: can't serialize properties: %m", myname);
+    return (vstring_str(buf));
+}
+
+/* tls_proxy_server_init_from_string - deserialize TLS_SERVER_INIT_PROPS */
+
+TLS_SERVER_INIT_PROPS *tls_proxy_server_init_from_string(
+                                                ATTR_SCAN_COMMON_FN scan_fn,
+                                                             VSTRING *buf)
+{
+    const char myname[] = "tls_proxy_server_init_from_string";
+    TLS_SERVER_INIT_PROPS *props = 0;
+    VSTREAM *mp;
+
+    if ((mp = vstream_memopen(buf, O_RDONLY)) == 0
+        || scan_fn(mp, ATTR_FLAG_NONE,
+                   RECV_ATTR_FUNC(tls_proxy_server_init_scan,
+                                  (void *) &props),
+                   ATTR_TYPE_END) != 1
+        || vstream_fclose(mp) != 0)
+        msg_fatal("%s: can't deserialize properties: %m", myname);
+    return (props);
+}
+
+/* tls_proxy_server_init_print - send TLS_SERVER_INIT_PROPS over stream */
+
+int     tls_proxy_server_init_print(ATTR_PRINT_COMMON_FN print_fn, VSTREAM *fp,
+                                           int flags, const void *ptr)
+{
+    const TLS_SERVER_INIT_PROPS *props = (const TLS_SERVER_INIT_PROPS *) ptr;
+    int     ret;
+
+#define STRING_OR_EMPTY(s) ((s) ? (s) : "")
+
+    ret = print_fn(fp, flags | ATTR_FLAG_MORE,
+                  SEND_ATTR_STR(TLS_ATTR_LOG_PARAM,
+                                STRING_OR_EMPTY(props->log_param)),
+                  SEND_ATTR_STR(TLS_ATTR_LOG_LEVEL,
+                                STRING_OR_EMPTY(props->log_level)),
+                  SEND_ATTR_INT(TLS_ATTR_VERIFYDEPTH, props->verifydepth),
+                  SEND_ATTR_STR(TLS_ATTR_CACHE_TYPE,
+                                STRING_OR_EMPTY(props->cache_type)),
+                  SEND_ATTR_INT(TLS_ATTR_SET_SESSID, props->set_sessid),
+                  SEND_ATTR_STR(TLS_ATTR_CHAIN_FILES,
+                                STRING_OR_EMPTY(props->chain_files)),
+                  SEND_ATTR_STR(TLS_ATTR_CERT_FILE,
+                                STRING_OR_EMPTY(props->cert_file)),
+                  SEND_ATTR_STR(TLS_ATTR_KEY_FILE,
+                                STRING_OR_EMPTY(props->key_file)),
+                  SEND_ATTR_STR(TLS_ATTR_DCERT_FILE,
+                                STRING_OR_EMPTY(props->dcert_file)),
+                  SEND_ATTR_STR(TLS_ATTR_DKEY_FILE,
+                                STRING_OR_EMPTY(props->dkey_file)),
+                  SEND_ATTR_STR(TLS_ATTR_ECCERT_FILE,
+                                STRING_OR_EMPTY(props->eccert_file)),
+                  SEND_ATTR_STR(TLS_ATTR_ECKEY_FILE,
+                                STRING_OR_EMPTY(props->eckey_file)),
+                  SEND_ATTR_STR(TLS_ATTR_CAFILE,
+                                STRING_OR_EMPTY(props->CAfile)),
+                  SEND_ATTR_STR(TLS_ATTR_CAPATH,
+                                STRING_OR_EMPTY(props->CApath)),
+                  SEND_ATTR_STR(TLS_ATTR_PROTOCOLS,
+                                STRING_OR_EMPTY(props->protocols)),
+                  SEND_ATTR_STR(TLS_ATTR_EECDH_GRADE,
+                                STRING_OR_EMPTY(props->eecdh_grade)),
+                  SEND_ATTR_STR(TLS_ATTR_DH1K_PARAM_FILE,
+                                STRING_OR_EMPTY(props->dh1024_param_file)),
+                  SEND_ATTR_STR(TLS_ATTR_DH512_PARAM_FILE,
+                                STRING_OR_EMPTY(props->dh512_param_file)),
+                  SEND_ATTR_INT(TLS_ATTR_ASK_CCERT, props->ask_ccert),
+                  SEND_ATTR_STR(TLS_ATTR_MDALG,
+                                STRING_OR_EMPTY(props->mdalg)),
+                  ATTR_TYPE_END);
+    /* Do not flush the stream. */
+    return (ret);
+}
 
 /* tls_proxy_server_init_scan - receive TLS_SERVER_INIT_PROPS from stream */
 
@@ -184,62 +292,4 @@ void    tls_proxy_server_init_free(TLS_SERVER_INIT_PROPS *props)
     myfree((void *) props);
 }
 
-/* tls_proxy_server_start_scan - receive TLS_SERVER_START_PROPS from stream */
-
-int     tls_proxy_server_start_scan(ATTR_SCAN_COMMON_FN scan_fn, VSTREAM *fp,
-                                           int flags, void *ptr)
-{
-    TLS_SERVER_START_PROPS *props
-    = (TLS_SERVER_START_PROPS *) mymalloc(sizeof(*props));
-    int     ret;
-    VSTRING *serverid = vstring_alloc(25);
-    VSTRING *namaddr = vstring_alloc(25);
-    VSTRING *cipher_grade = vstring_alloc(25);
-    VSTRING *cipher_exclusions = vstring_alloc(25);
-    VSTRING *mdalg = vstring_alloc(25);
-
-    /*
-     * Note: memset() is not a portable way to initialize non-integer types.
-     */
-    memset(props, 0, sizeof(*props));
-    props->ctx = 0;
-    props->stream = 0;
-    /* XXX Caller sets fd. */
-    ret = scan_fn(fp, flags | ATTR_FLAG_MORE,
-                 RECV_ATTR_INT(TLS_ATTR_TIMEOUT, &props->timeout),
-                 RECV_ATTR_INT(TLS_ATTR_REQUIRECERT, &props->requirecert),
-                 RECV_ATTR_STR(TLS_ATTR_SERVERID, serverid),
-                 RECV_ATTR_STR(TLS_ATTR_NAMADDR, namaddr),
-                 RECV_ATTR_STR(TLS_ATTR_CIPHER_GRADE, cipher_grade),
-                 RECV_ATTR_STR(TLS_ATTR_CIPHER_EXCLUSIONS,
-                               cipher_exclusions),
-                 RECV_ATTR_STR(TLS_ATTR_MDALG, mdalg),
-                 ATTR_TYPE_END);
-    props->serverid = vstring_export(serverid);
-    props->namaddr = vstring_export(namaddr);
-    props->cipher_grade = vstring_export(cipher_grade);
-    props->cipher_exclusions = vstring_export(cipher_exclusions);
-    props->mdalg = vstring_export(mdalg);
-    ret = (ret == 7 ? 1 : -1);
-    if (ret != 1) {
-       tls_proxy_server_start_free(props);
-       props = 0;
-    }
-    *(TLS_SERVER_START_PROPS **) ptr = props;
-    return (ret);
-}
-
-/* tls_proxy_server_start_free - destroy TLS_SERVER_START_PROPS structure */
-
-void    tls_proxy_server_start_free(TLS_SERVER_START_PROPS *props)
-{
-    /* XXX Caller closes fd. */
-    myfree((void *) props->serverid);
-    myfree((void *) props->namaddr);
-    myfree((void *) props->cipher_grade);
-    myfree((void *) props->cipher_exclusions);
-    myfree((void *) props->mdalg);
-    myfree((void *) props);
-}
-
 #endif
diff --git a/postfix/src/tls/tls_proxy_server_init_proto.h b/postfix/src/tls/tls_proxy_server_init_proto.h
new file mode 100644 (file)
index 0000000..0571b44
--- /dev/null
@@ -0,0 +1,63 @@
+#ifndef _TLS_PROXY_SERVER_INIT_PROTO_H_INCLUDED_
+#define _TLS_PROXY_SERVER_INIT_PROTO_H_INCLUDED_
+
+/*++
+/* NAME
+/*     tls_proxy_server_init_proto 3h
+/* SUMMARY
+/*     TLS_SERVER_START support
+/* SYNOPSIS
+/*     #include <tls_proxy_server_init_proto.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <vstream.h>
+#include <attr.h>
+
+ /*
+  * TLS library.
+  */
+#include <tls.h>
+
+#ifdef USE_TLS
+
+#define TLS_PROXY_SERVER_INIT_PROPS(props, a1, a2, a3, a4, a5, a6, a7, a8, \
+    a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) \
+    (((props)->a1), ((props)->a2), ((props)->a3), \
+    ((props)->a4), ((props)->a5), ((props)->a6), ((props)->a7), \
+    ((props)->a8), ((props)->a9), ((props)->a10), ((props)->a11), \
+    ((props)->a12), ((props)->a13), ((props)->a14), ((props)->a15), \
+    ((props)->a16), ((props)->a17), ((props)->a18), ((props)->a19), \
+    ((props)->a20))
+
+extern char *tls_proxy_server_init_serialize(ATTR_PRINT_COMMON_FN, VSTRING *, const TLS_SERVER_INIT_PROPS *);
+extern TLS_SERVER_INIT_PROPS *tls_proxy_server_init_from_string(ATTR_SCAN_COMMON_FN, VSTRING *);
+extern int tls_proxy_server_init_print(ATTR_PRINT_COMMON_FN, VSTREAM *, int, const void *);
+extern void tls_proxy_server_init_free(TLS_SERVER_INIT_PROPS *);
+extern int tls_proxy_server_init_scan(ATTR_SCAN_COMMON_FN, VSTREAM *, int, void *);
+
+#endif                                 /* USE_TLS */
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*
+/*     Wietse Venema
+/*     Google, Inc.
+/*     111 8th Avenue
+/*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif
diff --git a/postfix/src/tls/tls_proxy_server_init_proto_test.c b/postfix/src/tls/tls_proxy_server_init_proto_test.c
new file mode 100644 (file)
index 0000000..84363ca
--- /dev/null
@@ -0,0 +1,257 @@
+/*++
+/* NAME
+/*     tls_proxy_server_init_proto_test 1t
+/* SUMMARY
+/*     tls_proxy_server_init_proto unit test
+/* SYNOPSIS
+/*     ./tls_proxy_server_init_proto_test
+/* DESCRIPTION
+/*     tls_proxy_server_init_proto_test runs and logs each configured test, reports if
+/*     a test is a PASS or FAIL, and returns an exit status of zero if
+/*     all tests are a PASS.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+
+ /*
+  * Utility library.
+  */
+
+ /*
+  * Global library.
+  */
+#include <mail_params.h>
+
+ /*
+  * TLS library.
+  */
+#include <tls_proxy_server_init_proto.h>
+#include <tls_proxy_attr.h>
+
+ /*
+  * Test libraries.
+  */
+#include <ptest.h>
+#include <make_attr.h>
+#include <match_attr.h>
+
+ /*
+  * Test structure.
+  */
+typedef struct PTEST_CASE {
+    const char *testname;
+    void    (*action) (PTEST_CTX *, const struct PTEST_CASE *);
+} PTEST_CASE;
+
+#ifdef USE_TLS
+
+/*
+* Scaffolding: configuration parameters.
+*/
+char   *var_smtpd_tls_loglevel;
+int     var_smtpd_tls_ccert_vd;
+static char *cache_type;
+bool     var_smtpd_tls_set_sessid;
+char   *var_smtpd_tls_chain_files;
+char   *var_smtpd_tls_cert_file;
+char   *var_smtpd_tls_key_file;
+char   *var_smtpd_tls_dcert_file;
+char   *var_smtpd_tls_dkey_file;
+char   *var_smtpd_tls_eccert_file;
+char   *var_smtpd_tls_eckey_file;
+char   *var_smtpd_tls_CAfile;
+char   *var_smtpd_tls_CApath;
+char   *var_smtpd_tls_dh1024_param_file;
+char   *var_smtpd_tls_dh512_param_file;
+char   *var_smtpd_tls_eecdh;
+char   *var_smtpd_tls_proto;
+int     ask_ccert;
+char   *var_smtpd_tls_fpt_dgst;
+
+static void init_global_params(void)
+{
+    var_smtpd_tls_loglevel = DEF_SMTPD_TLS_LOGLEVEL;
+    var_smtpd_tls_ccert_vd = DEF_SMTPD_TLS_CCERT_VD;
+    cache_type = TLS_MGR_SCACHE_SMTPD;
+    var_smtpd_tls_set_sessid = DEF_SMTPD_TLS_SET_SESSID;
+    var_smtpd_tls_chain_files = DEF_SMTPD_TLS_CHAIN_FILES;
+    var_smtpd_tls_cert_file = DEF_SMTPD_TLS_CERT_FILE;
+    var_smtpd_tls_key_file = var_smtpd_tls_cert_file;
+    var_smtpd_tls_dcert_file = DEF_SMTPD_TLS_DCERT_FILE;
+    var_smtpd_tls_dkey_file = var_smtpd_tls_dcert_file;
+    var_smtpd_tls_eccert_file = DEF_SMTPD_TLS_ECCERT_FILE;
+    var_smtpd_tls_eckey_file = var_smtpd_tls_eccert_file;
+    var_smtpd_tls_CAfile = DEF_SMTPD_TLS_CA_FILE;
+    var_smtpd_tls_CApath = DEF_SMTPD_TLS_CA_PATH;
+    var_smtpd_tls_dh1024_param_file = DEF_SMTPD_TLS_1024_FILE;
+    var_smtpd_tls_dh512_param_file = DEF_SMTPD_TLS_512_FILE;
+    var_smtpd_tls_eecdh = DEF_SMTPD_TLS_EECDH;
+    var_smtpd_tls_proto = DEF_SMTPD_TLS_PROTO;
+    ask_ccert = 1,
+    var_smtpd_tls_fpt_dgst = DEF_SMTPD_TLS_FPT_DGST;
+}
+
+static void setup_reference_unserialized_init_props(TLS_SERVER_INIT_PROPS *props)
+{
+    TLS_PROXY_SERVER_INIT_PROPS(props,
+                               log_param = VAR_SMTPD_TLS_LOGLEVEL,
+                               log_level = var_smtpd_tls_loglevel,
+                               verifydepth = var_smtpd_tls_ccert_vd,
+                               cache_type = cache_type,
+                               set_sessid = var_smtpd_tls_set_sessid,
+                               chain_files = var_smtpd_tls_chain_files,
+                               cert_file = var_smtpd_tls_cert_file,
+                               key_file = var_smtpd_tls_key_file,
+                               dcert_file = var_smtpd_tls_dcert_file,
+                               dkey_file = var_smtpd_tls_dkey_file,
+                               eccert_file = var_smtpd_tls_eccert_file,
+                               eckey_file = var_smtpd_tls_eckey_file,
+                               CAfile = var_smtpd_tls_CAfile,
+                               CApath = var_smtpd_tls_CApath,
+                               dh1024_param_file
+                               = var_smtpd_tls_dh1024_param_file,
+                               dh512_param_file
+                               = var_smtpd_tls_dh512_param_file,
+                               eecdh_grade = var_smtpd_tls_eecdh,
+                               protocols = var_smtpd_tls_proto,
+                               ask_ccert = ask_ccert,
+                               mdalg = var_smtpd_tls_fpt_dgst);
+}
+
+static VSTRING *setup_reference_serialized_init_props(TLS_SERVER_INIT_PROPS *props)
+{
+
+    /*
+     * Note: this code is used to verify tls_proxy_server_init_print(), so we
+     * do not use that function here.
+     */
+#define STRING_OR_EMPTY(s) ((s) ? (s) : "")
+
+    return (make_attr(attr_vprint, ATTR_FLAG_NONE,
+                     SEND_ATTR_STR(TLS_ATTR_LOG_PARAM,
+                                   STRING_OR_EMPTY(props->log_param)),
+                     SEND_ATTR_STR(TLS_ATTR_LOG_LEVEL,
+                                   STRING_OR_EMPTY(props->log_level)),
+                     SEND_ATTR_INT(TLS_ATTR_VERIFYDEPTH,
+                                   props->verifydepth),
+                     SEND_ATTR_STR(TLS_ATTR_CACHE_TYPE,
+                                   STRING_OR_EMPTY(props->cache_type)),
+                     SEND_ATTR_INT(TLS_ATTR_SET_SESSID, props->set_sessid),
+                     SEND_ATTR_STR(TLS_ATTR_CHAIN_FILES,
+                                   STRING_OR_EMPTY(props->chain_files)),
+                     SEND_ATTR_STR(TLS_ATTR_CERT_FILE,
+                                   STRING_OR_EMPTY(props->cert_file)),
+                     SEND_ATTR_STR(TLS_ATTR_KEY_FILE,
+                                   STRING_OR_EMPTY(props->key_file)),
+                     SEND_ATTR_STR(TLS_ATTR_DCERT_FILE,
+                                   STRING_OR_EMPTY(props->dcert_file)),
+                     SEND_ATTR_STR(TLS_ATTR_DKEY_FILE,
+                                   STRING_OR_EMPTY(props->dkey_file)),
+                     SEND_ATTR_STR(TLS_ATTR_ECCERT_FILE,
+                                   STRING_OR_EMPTY(props->eccert_file)),
+                     SEND_ATTR_STR(TLS_ATTR_ECKEY_FILE,
+                                   STRING_OR_EMPTY(props->eckey_file)),
+                     SEND_ATTR_STR(TLS_ATTR_CAFILE,
+                                   STRING_OR_EMPTY(props->CAfile)),
+                     SEND_ATTR_STR(TLS_ATTR_CAPATH,
+                                   STRING_OR_EMPTY(props->CApath)),
+                     SEND_ATTR_STR(TLS_ATTR_PROTOCOLS,
+                                   STRING_OR_EMPTY(props->protocols)),
+                     SEND_ATTR_STR(TLS_ATTR_EECDH_GRADE,
+                                   STRING_OR_EMPTY(props->eecdh_grade)),
+                     SEND_ATTR_STR(TLS_ATTR_DH1K_PARAM_FILE,
+                                STRING_OR_EMPTY(props->dh1024_param_file)),
+                     SEND_ATTR_STR(TLS_ATTR_DH512_PARAM_FILE,
+                                 STRING_OR_EMPTY(props->dh512_param_file)),
+                     SEND_ATTR_INT(TLS_ATTR_ASK_CCERT, props->ask_ccert),
+                     SEND_ATTR_STR(TLS_ATTR_MDALG,
+                                   STRING_OR_EMPTY(props->mdalg)),
+                     ATTR_TYPE_END));
+}
+
+#endif
+
+/* Note: this also tests tls_proxy_server_init_print() */
+
+static void test_tls_proxy_server_init_serialize(PTEST_CTX *t,
+                                           const struct PTEST_CASE *unused)
+{
+#ifdef USE_TLS
+    TLS_SERVER_INIT_PROPS ref_unserialized_init_props;
+    VSTRING *got_serialized_init_props;
+    VSTRING *ref_serialized_init_props;
+
+    init_global_params();
+
+    setup_reference_unserialized_init_props(&ref_unserialized_init_props);
+
+    ref_serialized_init_props = setup_reference_serialized_init_props(
+                                             &ref_unserialized_init_props);
+
+    tls_proxy_server_init_serialize(attr_print,
+                            got_serialized_init_props = vstring_alloc(100),
+                              (const void *) &ref_unserialized_init_props);
+
+    (void) eq_attr(t, "tls_proxy_server_init_serialize",
+                  got_serialized_init_props, ref_serialized_init_props);
+#else
+    ptest_skip(t);
+#endif
+}
+
+/* Note: this also tests tls_proxy_server_init_scan() */
+
+static void test_tls_proxy_server_init_from_string(PTEST_CTX *t,
+                                           const struct PTEST_CASE *unused)
+{
+#ifdef USE_TLS
+    TLS_SERVER_INIT_PROPS ref_unserialized_init_props;
+    VSTRING *ref_serialized_init_props;
+    VSTRING *got_serialized_init_props;
+    TLS_SERVER_INIT_PROPS *deserialized_init_props;
+
+    init_global_params();
+
+    setup_reference_unserialized_init_props(&ref_unserialized_init_props);
+
+    ref_serialized_init_props = setup_reference_serialized_init_props(
+                                             &ref_unserialized_init_props);
+
+    deserialized_init_props = tls_proxy_server_init_from_string(attr_scan,
+                                                ref_serialized_init_props);
+    if (deserialized_init_props == 0)
+       ptest_fatal(t, "tls_proxy_server_init_from_string failed");
+
+    tls_proxy_server_init_serialize(attr_print,
+                            got_serialized_init_props = vstring_alloc(100),
+                                   deserialized_init_props);
+
+    eq_attr(t, "tls_proxy_server_init_from_string",
+           got_serialized_init_props, ref_serialized_init_props);
+
+    vstring_free(ref_serialized_init_props);
+    vstring_free(got_serialized_init_props);
+#else
+    ptest_skip(t);
+#endif
+}
+
+ /*
+  * The list of test cases.
+  */
+static const PTEST_CASE ptestcases[] = {
+    "test_tls_proxy_server_init_serialize", test_tls_proxy_server_init_serialize,
+    "test_tls_proxy_server_init_from_string", test_tls_proxy_server_init_from_string,
+};
+
+#include <ptest_main.h>
diff --git a/postfix/src/tls/tls_proxy_server_param_proto.c b/postfix/src/tls/tls_proxy_server_param_proto.c
new file mode 100644 (file)
index 0000000..7675f26
--- /dev/null
@@ -0,0 +1,333 @@
+/*++
+/* NAME
+/*     tls_proxy_server_param_proto 3
+/* SUMMARY
+/*     TLS_SERVER_PARAMS structure support
+/* SYNOPSIS
+/*     #include <tls_proxy_server_param_proto.h>
+/*
+/*     TLS_SERVER_PARAMS *tls_proxy_server_param_from_config(params)
+/*     TLS_SERVER_PARAMS *params;
+/*
+/*     char    *tls_proxy_server_param_serialize(print_fn, buf, params)
+/*     ATTR_PRINT_COMMON_FN print_fn;
+/*     VSTRING *buf;
+/*     const TLS_SERVER_PARAMS *params;
+/*
+/*     TLS_SERVER_PARAMS *tls_proxy_server_param_from_string(
+/*     ATTR_SCAN_COMMON_FN scan_fn,
+/*     const VSTRING *buf)
+/*
+/*     int     tls_proxy_server_param_print(print_fn, stream, flags, ptr)
+/*     ATTR_PRINT_COMMON_FN print_fn;
+/*     VSTREAM *stream;
+/*     int     flags;
+/*     const void *ptr;
+/*
+/*     int     tls_proxy_server_param_scan(scan_fn, stream, flags, ptr)
+/*     ATTR_SCAN_COMMON_FN scan_fn;
+/*     VSTREAM *stream;
+/*     int     flags;
+/*     void    *ptr;
+/*
+/*     void    tls_proxy_server_param_free(params)
+/*     TLS_SERVER_PARAMS *params;
+/* DESCRIPTION
+/*     tls_proxy_server_param_from_config() initializes a
+/*     TLS_SERVER_PARAMS structure from configuration parameters and
+/*     returns its argument. Strings are not copied. The result must
+/*     therefore not be passed to tls_proxy_server_param_free().
+/*
+/*     tls_proxy_server_param_serialize() serializes the specified object
+/*     to a memory buffer, using the specified print function (typically,
+/*     attr_print_plain). The result can be used determine whether
+/*     there are any differences between instances of the same object
+/*     type.
+/*
+/*     tls_proxy_server_param_from_string() deserializes the specified
+/*     buffer into a TLS_SERVER_PARAMS object, and returns null in case
+/*     of error. The result if not null should be passed to
+/*     tls_proxy_server_param_free().
+/*
+/*     tls_proxy_server_param_print() writes a TLS_SERVER_PARAMS
+/*     structure to the named stream using the specified attribute
+/*     print routine. tls_proxy_server_param_print() is meant to be
+/*     passed as a call-back to attr_print(), thusly:
+/*
+/*     SEND_ATTR_FUNC(tls_proxy_server_param_print, (const void *) param), ...
+/*
+/*      tls_proxy_server_param_scan() reads a TLS_SERVER_PARAMS structure
+/*      from the named stream using the specified attribute scan routine.
+/*      tls_proxy_server_param_scan() is meant to be passed as a call-back
+/*      function to attr_scan(), as shown below.
+/*
+/*      tls_proxy_server_param_free() destroys a TLS_SERVER_PARAMS structure
+/*      that was created by tls_proxy_server_param_scan().
+/*
+/*      TLS_SERVER_PARAMS *param = 0;
+/*      ...
+/*      ... RECV_ATTR_FUNC(tls_proxy_server_param_scan, (void *) &param)
+/*      ...
+/*      if (param != 0)
+/*          tls_proxy_server_param_free(param);
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     Google, Inc.
+/*     111 8th Avenue
+/*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#ifdef USE_TLS
+
+/* System library. */
+
+#include <sys_defs.h>
+
+/* Utility library */
+
+#include <attr.h>
+#include <msg.h>
+
+/* Global library. */
+
+#include <mail_params.h>
+
+/* TLS library. */
+
+#include <tls.h>
+#include <tls_proxy_attr.h>
+#include <tls_proxy_server_param_proto.h>
+
+/* tls_proxy_server_param_from_config - initialize TLS_SERVER_PARAMS from configuration */
+
+TLS_SERVER_PARAMS *tls_proxy_server_param_from_config(TLS_SERVER_PARAMS *params)
+{
+    TLS_PROXY_SERVER_PARAMS(params,
+                           tls_cnf_file = var_tls_cnf_file,
+                           tls_cnf_name = var_tls_cnf_name,
+                           tls_high_clist = var_tls_high_clist,
+                           tls_medium_clist = var_tls_medium_clist,
+                           tls_null_clist = var_tls_null_clist,
+                           tls_eecdh_auto = var_tls_eecdh_auto,
+                           tls_eecdh_strong = var_tls_eecdh_strong,
+                           tls_eecdh_ultra = var_tls_eecdh_ultra,
+                           tls_ffdhe_auto = var_tls_ffdhe_auto,
+                           tls_bug_tweaks = var_tls_bug_tweaks,
+                           tls_ssl_options = var_tls_ssl_options,
+                           tls_mgr_service = var_tls_mgr_service,
+                           tls_tkt_cipher = var_tls_tkt_cipher,
+                         tls_daemon_rand_bytes = var_tls_daemon_rand_bytes,
+                           tls_append_def_CA = var_tls_append_def_CA,
+                           tls_preempt_clist = var_tls_preempt_clist,
+                           tls_multi_wildcard = var_tls_multi_wildcard,
+                           tls_server_sni_maps = var_tls_server_sni_maps,
+                           tls_fast_shutdown = var_tls_fast_shutdown,
+                           tls_srvr_ccerts = var_tls_srvr_ccerts);
+    return (params);
+}
+
+/* tls_proxy_server_param_serialize - serialize TLS_SERVER_PARAMS to string */
+
+char   *tls_proxy_server_param_serialize(ATTR_PRINT_COMMON_FN print_fn,
+                                                VSTRING *buf,
+                                           const TLS_SERVER_PARAMS *params)
+{
+    const char myname[] = "tls_proxy_server_param_serialize";
+    VSTREAM *mp;
+
+    if ((mp = vstream_memopen(buf, O_WRONLY)) == 0
+       || print_fn(mp, ATTR_FLAG_NONE,
+                   SEND_ATTR_FUNC(tls_proxy_server_param_print,
+                                  (const void *) params),
+                   ATTR_TYPE_END) != 0
+       || vstream_fclose(mp) != 0)
+       msg_fatal("%s: can't serialize properties: %m", myname);
+    return (vstring_str(buf));
+}
+
+/* tls_proxy_server_param_from_string - deserialize TLS_SERVER_PARAMS */
+
+TLS_SERVER_PARAMS *tls_proxy_server_param_from_string(
+                                               ATTR_SCAN_COMMON_FN scan_fn,
+                                                             VSTRING *buf)
+{
+    const char myname[] = "tls_proxy_server_param_from_string";
+    TLS_SERVER_PARAMS *params = 0;
+    VSTREAM *mp;
+
+    if ((mp = vstream_memopen(buf, O_RDONLY)) == 0
+       || scan_fn(mp, ATTR_FLAG_NONE,
+                  RECV_ATTR_FUNC(tls_proxy_server_param_scan,
+                                 (void *) &params),
+                  ATTR_TYPE_END) != 1
+       || vstream_fclose(mp) != 0)
+       msg_fatal("%s: can't deserialize properties: %m", myname);
+    return (params);
+}
+
+/* tls_proxy_server_param_print - send TLS_SERVER_PARAMS over stream */
+
+int     tls_proxy_server_param_print(ATTR_PRINT_COMMON_FN print_fn, VSTREAM *fp,
+                                            int flags, const void *ptr)
+{
+    const TLS_SERVER_PARAMS *params = (const TLS_SERVER_PARAMS *) ptr;
+    int     ret;
+
+    if (msg_verbose)
+       msg_info("begin tls_proxy_server_param_print");
+
+    ret = print_fn(fp, flags | ATTR_FLAG_MORE,
+                  SEND_ATTR_STR(TLS_ATTR_CNF_FILE, params->tls_cnf_file),
+                  SEND_ATTR_STR(TLS_ATTR_CNF_NAME, params->tls_cnf_name),
+                  SEND_ATTR_STR(VAR_TLS_HIGH_CLIST, params->tls_high_clist),
+                  SEND_ATTR_STR(VAR_TLS_MEDIUM_CLIST,
+                                params->tls_medium_clist),
+                  SEND_ATTR_STR(VAR_TLS_NULL_CLIST, params->tls_null_clist),
+                  SEND_ATTR_STR(VAR_TLS_EECDH_AUTO, params->tls_eecdh_auto),
+                  SEND_ATTR_STR(VAR_TLS_EECDH_STRONG,
+                                params->tls_eecdh_strong),
+                  SEND_ATTR_STR(VAR_TLS_EECDH_ULTRA,
+                                params->tls_eecdh_ultra),
+                  SEND_ATTR_STR(VAR_TLS_FFDHE_AUTO, params->tls_ffdhe_auto),
+                  SEND_ATTR_STR(VAR_TLS_BUG_TWEAKS, params->tls_bug_tweaks),
+                  SEND_ATTR_STR(VAR_TLS_SSL_OPTIONS,
+                                params->tls_ssl_options),
+                  SEND_ATTR_STR(VAR_TLS_MGR_SERVICE,
+                                params->tls_mgr_service),
+                  SEND_ATTR_STR(VAR_TLS_TKT_CIPHER, params->tls_tkt_cipher),
+                  SEND_ATTR_INT(VAR_TLS_DAEMON_RAND_BYTES,
+                                params->tls_daemon_rand_bytes),
+                  SEND_ATTR_INT(VAR_TLS_APPEND_DEF_CA,
+                                params->tls_append_def_CA),
+                  SEND_ATTR_INT(VAR_TLS_PREEMPT_CLIST,
+                                params->tls_preempt_clist),
+                  SEND_ATTR_INT(VAR_TLS_MULTI_WILDCARD,
+                                params->tls_multi_wildcard),
+                  SEND_ATTR_STR(VAR_TLS_SERVER_SNI_MAPS,
+                                params->tls_server_sni_maps),
+                  SEND_ATTR_INT(VAR_TLS_FAST_SHUTDOWN,
+                                params->tls_fast_shutdown),
+                  SEND_ATTR_INT(VAR_TLS_SRVR_CCERTS,
+                                params->tls_srvr_ccerts),
+                  ATTR_TYPE_END);
+    /* Do not flush the stream. */
+    if (msg_verbose)
+       msg_info("tls_proxy_server_param_print ret=%d", ret);
+    return (ret);
+}
+
+/* tls_proxy_server_param_scan - receive TLS_SERVER_PARAMS from stream */
+
+int     tls_proxy_server_param_scan(ATTR_SCAN_COMMON_FN scan_fn, VSTREAM *fp,
+                                           int flags, void *ptr)
+{
+    TLS_SERVER_PARAMS *params
+    = (TLS_SERVER_PARAMS *) mymalloc(sizeof(*params));
+    int     ret;
+    VSTRING *cnf_file = vstring_alloc(25);
+    VSTRING *cnf_name = vstring_alloc(25);
+    VSTRING *tls_high_clist = vstring_alloc(25);
+    VSTRING *tls_medium_clist = vstring_alloc(25);
+    VSTRING *tls_null_clist = vstring_alloc(25);
+    VSTRING *tls_eecdh_auto = vstring_alloc(25);
+    VSTRING *tls_eecdh_strong = vstring_alloc(25);
+    VSTRING *tls_eecdh_ultra = vstring_alloc(25);
+    VSTRING *tls_ffdhe_auto = vstring_alloc(25);
+    VSTRING *tls_bug_tweaks = vstring_alloc(25);
+    VSTRING *tls_ssl_options = vstring_alloc(25);
+    VSTRING *tls_mgr_service = vstring_alloc(25);
+    VSTRING *tls_tkt_cipher = vstring_alloc(25);
+    VSTRING *tls_server_sni_maps = vstring_alloc(25);
+
+    if (msg_verbose)
+       msg_info("begin tls_proxy_server_param_scan");
+
+    /*
+     * Note: memset() is not a portable way to initialize non-integer types.
+     */
+    memset(params, 0, sizeof(*params));
+    ret = scan_fn(fp, flags | ATTR_FLAG_MORE,
+                 RECV_ATTR_STR(TLS_ATTR_CNF_FILE, cnf_file),
+                 RECV_ATTR_STR(TLS_ATTR_CNF_NAME, cnf_name),
+                 RECV_ATTR_STR(VAR_TLS_HIGH_CLIST, tls_high_clist),
+                 RECV_ATTR_STR(VAR_TLS_MEDIUM_CLIST, tls_medium_clist),
+                 RECV_ATTR_STR(VAR_TLS_NULL_CLIST, tls_null_clist),
+                 RECV_ATTR_STR(VAR_TLS_EECDH_AUTO, tls_eecdh_auto),
+                 RECV_ATTR_STR(VAR_TLS_EECDH_STRONG, tls_eecdh_strong),
+                 RECV_ATTR_STR(VAR_TLS_EECDH_ULTRA, tls_eecdh_ultra),
+                 RECV_ATTR_STR(VAR_TLS_FFDHE_AUTO, tls_ffdhe_auto),
+                 RECV_ATTR_STR(VAR_TLS_BUG_TWEAKS, tls_bug_tweaks),
+                 RECV_ATTR_STR(VAR_TLS_SSL_OPTIONS, tls_ssl_options),
+                 RECV_ATTR_STR(VAR_TLS_MGR_SERVICE, tls_mgr_service),
+                 RECV_ATTR_STR(VAR_TLS_TKT_CIPHER, tls_tkt_cipher),
+                 RECV_ATTR_INT(VAR_TLS_DAEMON_RAND_BYTES,
+                               &params->tls_daemon_rand_bytes),
+                 RECV_ATTR_INT(VAR_TLS_APPEND_DEF_CA,
+                               &params->tls_append_def_CA),
+                 RECV_ATTR_INT(VAR_TLS_PREEMPT_CLIST,
+                               &params->tls_preempt_clist),
+                 RECV_ATTR_INT(VAR_TLS_MULTI_WILDCARD,
+                               &params->tls_multi_wildcard),
+                 RECV_ATTR_STR(VAR_TLS_SERVER_SNI_MAPS,
+                               tls_server_sni_maps),
+                 RECV_ATTR_INT(VAR_TLS_FAST_SHUTDOWN,
+                               &params->tls_fast_shutdown),
+                 RECV_ATTR_INT(VAR_TLS_SRVR_CCERTS,
+                               &params->tls_srvr_ccerts),
+                 ATTR_TYPE_END);
+    /* Always construct a well-formed structure. */
+    params->tls_cnf_file = vstring_export(cnf_file);
+    params->tls_cnf_name = vstring_export(cnf_name);
+    params->tls_high_clist = vstring_export(tls_high_clist);
+    params->tls_medium_clist = vstring_export(tls_medium_clist);
+    params->tls_null_clist = vstring_export(tls_null_clist);
+    params->tls_eecdh_auto = vstring_export(tls_eecdh_auto);
+    params->tls_eecdh_strong = vstring_export(tls_eecdh_strong);
+    params->tls_eecdh_ultra = vstring_export(tls_eecdh_ultra);
+    params->tls_ffdhe_auto = vstring_export(tls_ffdhe_auto);
+    params->tls_bug_tweaks = vstring_export(tls_bug_tweaks);
+    params->tls_ssl_options = vstring_export(tls_ssl_options);
+    params->tls_mgr_service = vstring_export(tls_mgr_service);
+    params->tls_tkt_cipher = vstring_export(tls_tkt_cipher);
+    params->tls_server_sni_maps = vstring_export(tls_server_sni_maps);
+
+    ret = (ret == 20 ? 1 : -1);
+    if (ret != 1) {
+       tls_proxy_server_param_free(params);
+       params = 0;
+    }
+    *(TLS_SERVER_PARAMS **) ptr = params;
+    if (msg_verbose)
+       msg_info("tls_proxy_server_param_scan ret=%d", ret);
+    return (ret);
+}
+
+/* tls_proxy_server_param_free - destroy TLS_SERVER_PARAMS structure */
+
+void    tls_proxy_server_param_free(TLS_SERVER_PARAMS *params)
+{
+    myfree(params->tls_cnf_file);
+    myfree(params->tls_cnf_name);
+    myfree(params->tls_high_clist);
+    myfree(params->tls_medium_clist);
+    myfree(params->tls_null_clist);
+    myfree(params->tls_eecdh_auto);
+    myfree(params->tls_eecdh_strong);
+    myfree(params->tls_eecdh_ultra);
+    myfree(params->tls_ffdhe_auto);
+    myfree(params->tls_bug_tweaks);
+    myfree(params->tls_ssl_options);
+    myfree(params->tls_mgr_service);
+    myfree(params->tls_tkt_cipher);
+    myfree(params->tls_server_sni_maps);
+    myfree((void *) params);
+}
+
+#endif
diff --git a/postfix/src/tls/tls_proxy_server_param_proto.h b/postfix/src/tls/tls_proxy_server_param_proto.h
new file mode 100644 (file)
index 0000000..ddfa6bd
--- /dev/null
@@ -0,0 +1,98 @@
+#ifndef _TLS_PROXY_SERVER_PARAM_PROTO_H_INCLUDED_
+#define _TLS_PROXY_SERVER_PARAM_PROTO_H_INCLUDED_
+
+/*++
+/* NAME
+/*     tls_proxy_server_param_proto 3h
+/* SUMMARY
+/*     TLS proxy protocol support
+/* SYNOPSIS
+/*     #include <tls_proxy_server_param_proto.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <vstream.h>
+#include <attr.h>
+
+ /*
+  * TLS library.
+  */
+#include <tls.h>
+
+#ifdef USE_TLS
+
+ /*
+  * TLS_SERVER_PARAMS structure, to communicate global TLS library settings
+  * that are the same for all TLS server contexts. This information is used
+  * in tlsproxy(8) to detect inconsistencies. If this structure is changed,
+  * update all TLS_SERVER_PARAMS related functions in tls_proxy_server_*.c.
+  * 
+  * In the serialization these attributes are identified by their configuration
+  * parameter names.
+  * 
+  * NOTE: this does not include openssl_path.
+  */
+typedef struct TLS_SERVER_PARAMS {
+    char   *tls_cnf_file;
+    char   *tls_cnf_name;
+    char   *tls_high_clist;
+    char   *tls_medium_clist;
+    char   *tls_null_clist;
+    char   *tls_eecdh_auto;
+    char   *tls_eecdh_strong;
+    char   *tls_eecdh_ultra;
+    char   *tls_ffdhe_auto;
+    char   *tls_bug_tweaks;
+    char   *tls_ssl_options;
+    char   *tls_mgr_service;
+    char   *tls_tkt_cipher;
+    int     tls_daemon_rand_bytes;
+    int     tls_append_def_CA;
+    int     tls_preempt_clist;
+    int     tls_multi_wildcard;
+    char   *tls_server_sni_maps;
+    int     tls_fast_shutdown;
+    int     tls_srvr_ccerts;
+} TLS_SERVER_PARAMS;
+
+#define TLS_PROXY_SERVER_PARAMS(params, a1, a2, a3, a4, a5, a6, a7, a8, \
+    a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) \
+    (((params)->a1), ((params)->a2), ((params)->a3), \
+    ((params)->a4), ((params)->a5), ((params)->a6), ((params)->a7), \
+    ((params)->a8), ((params)->a9), ((params)->a10), ((params)->a11), \
+    ((params)->a12), ((params)->a13), ((params)->a14), ((params)->a15), \
+    ((params)->a16), ((params)->a17), ((params)->a18), ((params)->a19), \
+    ((params)->a20))
+
+extern TLS_SERVER_PARAMS *tls_proxy_server_param_from_config(TLS_SERVER_PARAMS *);
+extern char *tls_proxy_server_param_serialize(ATTR_PRINT_COMMON_FN, VSTRING *, const TLS_SERVER_PARAMS *);
+extern TLS_SERVER_PARAMS *tls_proxy_server_param_from_string(ATTR_SCAN_COMMON_FN, VSTRING *);
+extern int tls_proxy_server_param_print(ATTR_PRINT_COMMON_FN, VSTREAM *, int, const void *);
+extern void tls_proxy_server_param_free(TLS_SERVER_PARAMS *);
+extern int tls_proxy_server_param_scan(ATTR_SCAN_COMMON_FN, VSTREAM *, int, void *);
+
+#endif                                 /* USE_TLS */
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*
+/*     Wietse Venema
+/*     Google, Inc.
+/*     111 8th Avenue
+/*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif
diff --git a/postfix/src/tls/tls_proxy_server_param_proto_test.c b/postfix/src/tls/tls_proxy_server_param_proto_test.c
new file mode 100644 (file)
index 0000000..c68be0e
--- /dev/null
@@ -0,0 +1,290 @@
+/*++
+/* NAME
+/*     tls_proxy_server_param_proto_test 1t
+/* SUMMARY
+/*     tls_proxy_server_param_proto unit test
+/* SYNOPSIS
+/*     ./tls_proxy_server_param_proto_test
+/* DESCRIPTION
+/*     tls_proxy_server_param_proto_test runs and logs each configured test, reports if
+/*     a test is a PASS or FAIL, and returns an exit status of zero if
+/*     all tests are a PASS.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+
+ /*
+  * Utility library.
+  */
+
+ /*
+  * Global library.
+  */
+#include <mail_params.h>
+
+ /*
+  * TLS library.
+  */
+#include <tls_proxy_server_param_proto.h>
+#include <tls_proxy_attr.h>
+
+ /*
+  * Test libraries.
+  */
+#include <ptest.h>
+#include <make_attr.h>
+#include <match_attr.h>
+
+ /*
+  * Test structure.
+  */
+typedef struct PTEST_CASE {
+    const char *testname;
+    void    (*action) (PTEST_CTX *, const struct PTEST_CASE *);
+} PTEST_CASE;
+
+#ifdef USE_TLS
+
+ /*
+  * Scaffolding: configuration parameters.
+  */
+char   *var_tls_cnf_file;
+char   *var_tls_cnf_name;
+char   *var_tls_high_clist;
+char   *var_tls_medium_clist;
+char   *var_tls_null_clist;
+char   *var_tls_eecdh_auto;
+char   *var_tls_eecdh_strong;
+char   *var_tls_eecdh_ultra;
+char   *var_tls_ffdhe_auto;
+char   *var_tls_bug_tweaks;
+char   *var_tls_ssl_options;
+char   *var_tls_mgr_service;
+char   *var_tls_tkt_cipher;
+int     var_tls_daemon_rand_bytes;
+bool    var_tls_append_def_CA;
+bool    var_tls_preempt_clist;
+bool    var_tls_multi_wildcard;
+char   *var_tls_server_sni_maps;
+bool    var_tls_fast_shutdown;
+bool    var_tls_srvr_ccerts;
+
+static void init_global_params(void)
+{
+    var_tls_cnf_file = DEF_TLS_CNF_FILE;
+    var_tls_cnf_name = DEF_TLS_CNF_NAME;
+    var_tls_high_clist = DEF_TLS_HIGH_CLIST;
+    var_tls_medium_clist = DEF_TLS_MEDIUM_CLIST;
+    var_tls_null_clist = DEF_TLS_NULL_CLIST;
+    var_tls_eecdh_auto = DEF_TLS_EECDH_AUTO;
+    var_tls_eecdh_strong = DEF_TLS_EECDH_STRONG;
+    var_tls_eecdh_ultra = DEF_TLS_EECDH_ULTRA;
+    var_tls_ffdhe_auto = DEF_TLS_FFDHE_AUTO;
+    var_tls_bug_tweaks = DEF_TLS_BUG_TWEAKS;
+    var_tls_ssl_options = DEF_TLS_SSL_OPTIONS;
+    var_tls_mgr_service = DEF_TLS_MGR_SERVICE;
+    var_tls_tkt_cipher = DEF_TLS_TKT_CIPHER;
+    var_tls_daemon_rand_bytes = DEF_TLS_DAEMON_RAND_BYTES;
+    var_tls_append_def_CA = DEF_TLS_APPEND_DEF_CA;
+    var_tls_preempt_clist = DEF_TLS_PREEMPT_CLIST;
+    var_tls_multi_wildcard = DEF_TLS_MULTI_WILDCARD;
+    var_tls_server_sni_maps = DEF_TLS_SERVER_SNI_MAPS;
+    var_tls_fast_shutdown = DEF_TLS_FAST_SHUTDOWN;
+    var_tls_srvr_ccerts = DEF_TLS_SRVR_CCERTS;
+}
+
+static void setup_reference_unserialized_params(TLS_SERVER_PARAMS *params)
+{
+    TLS_PROXY_SERVER_PARAMS(params,
+                           tls_cnf_file = var_tls_cnf_file,
+                           tls_cnf_name = var_tls_cnf_name,
+                           tls_high_clist = var_tls_high_clist,
+                           tls_medium_clist = var_tls_medium_clist,
+                           tls_null_clist = var_tls_null_clist,
+                           tls_eecdh_auto = var_tls_eecdh_auto,
+                           tls_eecdh_strong = var_tls_eecdh_strong,
+                           tls_eecdh_ultra = var_tls_eecdh_ultra,
+                           tls_ffdhe_auto = var_tls_ffdhe_auto,
+                           tls_bug_tweaks = var_tls_bug_tweaks,
+                           tls_ssl_options = var_tls_ssl_options,
+                           tls_mgr_service = var_tls_mgr_service,
+                           tls_tkt_cipher = var_tls_tkt_cipher,
+                         tls_daemon_rand_bytes = var_tls_daemon_rand_bytes,
+                           tls_append_def_CA = var_tls_append_def_CA,
+                           tls_preempt_clist = var_tls_preempt_clist,
+                           tls_multi_wildcard = var_tls_multi_wildcard,
+                           tls_server_sni_maps = var_tls_server_sni_maps,
+                           tls_fast_shutdown = var_tls_fast_shutdown,
+                           tls_srvr_ccerts = var_tls_srvr_ccerts);
+}
+
+static VSTRING *setup_reference_serialized_params(TLS_SERVER_PARAMS *params)
+{
+    return (make_attr(attr_vprint, ATTR_FLAG_NONE,
+                     SEND_ATTR_STR(TLS_ATTR_CNF_FILE, params->tls_cnf_file),
+                     SEND_ATTR_STR(TLS_ATTR_CNF_NAME, params->tls_cnf_name),
+                     SEND_ATTR_STR(VAR_TLS_HIGH_CLIST,
+                                   params->tls_high_clist),
+                     SEND_ATTR_STR(VAR_TLS_MEDIUM_CLIST,
+                                   params->tls_medium_clist),
+                     SEND_ATTR_STR(VAR_TLS_NULL_CLIST,
+                                   params->tls_null_clist),
+                     SEND_ATTR_STR(VAR_TLS_EECDH_AUTO,
+                                   params->tls_eecdh_auto),
+                     SEND_ATTR_STR(VAR_TLS_EECDH_STRONG,
+                                   params->tls_eecdh_strong),
+                     SEND_ATTR_STR(VAR_TLS_EECDH_ULTRA,
+                                   params->tls_eecdh_ultra),
+                     SEND_ATTR_STR(VAR_TLS_FFDHE_AUTO,
+                                   params->tls_ffdhe_auto),
+                     SEND_ATTR_STR(VAR_TLS_BUG_TWEAKS,
+                                   params->tls_bug_tweaks),
+                     SEND_ATTR_STR(VAR_TLS_SSL_OPTIONS,
+                                   params->tls_ssl_options),
+                     SEND_ATTR_STR(VAR_TLS_MGR_SERVICE,
+                                   params->tls_mgr_service),
+                     SEND_ATTR_STR(VAR_TLS_TKT_CIPHER,
+                                   params->tls_tkt_cipher),
+                     SEND_ATTR_INT(VAR_TLS_DAEMON_RAND_BYTES,
+                                   params->tls_daemon_rand_bytes),
+                     SEND_ATTR_INT(VAR_TLS_APPEND_DEF_CA,
+                                   params->tls_append_def_CA),
+                     SEND_ATTR_INT(VAR_TLS_PREEMPT_CLIST,
+                                   params->tls_preempt_clist),
+                     SEND_ATTR_INT(VAR_TLS_MULTI_WILDCARD,
+                                   params->tls_multi_wildcard),
+                     SEND_ATTR_STR(VAR_TLS_SERVER_SNI_MAPS,
+                                   params->tls_server_sni_maps),
+                     SEND_ATTR_INT(VAR_TLS_FAST_SHUTDOWN,
+                                   params->tls_fast_shutdown),
+                     SEND_ATTR_INT(VAR_TLS_SRVR_CCERTS,
+                                   params->tls_srvr_ccerts),
+                     ATTR_TYPE_END));
+}
+
+#endif
+
+/* Note: this also tests tls_proxy_server_param_print() */
+
+static void test_tls_proxy_server_param_serialize(PTEST_CTX *t,
+                                           const struct PTEST_CASE *unused)
+{
+#ifdef USE_TLS
+    TLS_SERVER_PARAMS ref_unserialized_params;
+    VSTRING *got_serialized_params;
+    VSTRING *ref_serialized_params;
+
+    init_global_params();
+
+    setup_reference_unserialized_params(&ref_unserialized_params);
+
+    ref_serialized_params = setup_reference_serialized_params(
+                                                 &ref_unserialized_params);
+
+    tls_proxy_server_param_serialize(attr_print,
+                                got_serialized_params = vstring_alloc(100),
+                                  (const void *) &ref_unserialized_params);
+
+    (void) eq_attr(t, "tls_proxy_server_param_serialize",
+                  got_serialized_params, ref_serialized_params);
+#else
+    ptest_skip(t);
+#endif
+}
+
+static void test_tls_proxy_server_param_from_config(PTEST_CTX *t,
+                                           const struct PTEST_CASE *unused)
+{
+#ifdef USE_TLS
+    TLS_SERVER_PARAMS ref_unserialized_params;
+    TLS_SERVER_PARAMS got_server_params;
+    TLS_SERVER_PARAMS *p;
+    VSTRING *want_server_params_serialized;
+    VSTRING *got_server_params_serialized;
+
+    init_global_params();
+
+    setup_reference_unserialized_params(&ref_unserialized_params);
+
+    tls_proxy_server_param_serialize(attr_print,
+                        want_server_params_serialized = vstring_alloc(100),
+                                    &ref_unserialized_params);
+
+    init_global_params();
+
+    p = tls_proxy_server_param_from_config(&got_server_params);
+    if (p != &got_server_params)
+       ptest_fatal(t, "unexpected tls_proxy_server_param_from_config() result: got %p, and %p",
+                   (void *) p, (void *) &got_server_params);
+
+    tls_proxy_server_param_serialize(attr_print,
+                         got_server_params_serialized = vstring_alloc(100),
+                                    &got_server_params);
+
+    (void) eq_attr(t, "tls_proxy_server_param_from_config",
+              got_server_params_serialized, want_server_params_serialized);
+
+    vstring_free(want_server_params_serialized);
+    vstring_free(got_server_params_serialized);
+#else
+    ptest_skip(t);
+#endif
+}
+
+/* Note: this also tests tls_proxy_server_param_scan() */
+
+static void test_tls_proxy_server_param_from_string(PTEST_CTX *t,
+                                           const struct PTEST_CASE *unused)
+{
+#ifdef USE_TLS
+    TLS_SERVER_PARAMS ref_unserialized_params;
+    VSTRING *ref_serialized_params;
+    VSTRING *got_serialized_params;
+    TLS_SERVER_PARAMS *deserialized_params;
+
+    init_global_params();
+
+    setup_reference_unserialized_params(&ref_unserialized_params);
+
+    ref_serialized_params = setup_reference_serialized_params(
+                                                 &ref_unserialized_params);
+
+    deserialized_params = tls_proxy_server_param_from_string(attr_scan,
+                                                    ref_serialized_params);
+    if (deserialized_params == 0)
+       ptest_fatal(t, "tls_proxy_server_param_from_string failed");
+
+    tls_proxy_server_param_serialize(attr_print,
+                                got_serialized_params = vstring_alloc(100),
+                                    deserialized_params);
+
+    eq_attr(t, "tls_proxy_server_param_from_string",
+           got_serialized_params, ref_serialized_params);
+
+    vstring_free(ref_serialized_params);
+    vstring_free(got_serialized_params);
+#else
+    ptest_skip(t);
+#endif
+}
+
+ /*
+  * The list of test cases.
+  */
+static const PTEST_CASE ptestcases[] = {
+    "test_tls_proxy_server_param_serialize", test_tls_proxy_server_param_serialize,
+    "test_tls_proxy_server_param_from_config", test_tls_proxy_server_param_from_config,
+    "test_tls_proxy_server_param_from_string", test_tls_proxy_server_param_from_string,
+};
+
+#include <ptest_main.h>
diff --git a/postfix/src/tls/tls_proxy_server_print.c b/postfix/src/tls/tls_proxy_server_print.c
deleted file mode 100644 (file)
index 8d51422..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*++
-/* NAME
-/*     tls_proxy_server_print 3
-/* SUMMARY
-/*     write TLS_SERVER_XXX structures to stream
-/* SYNOPSIS
-/*     #include <tls_proxy.h>
-/*
-/*     int     tls_proxy_server_init_print(print_fn, stream, flags, ptr)
-/*     ATTR_PRINT_COMMON_FN print_fn;
-/*     VSTREAM *stream;
-/*     int     flags;
-/*     void    *ptr;
-/*
-/*     int     tls_proxy_server_start_print(print_fn, stream, flags, ptr)
-/*     ATTR_PRINT_COMMON_FN print_fn;
-/*     VSTREAM *stream;
-/*     int     flags;
-/*     void    *ptr;
-/* DESCRIPTION
-/*     tls_proxy_server_init_print() writes a TLS_SERVER_INIT_PROPS
-/*     structure to the named stream using the specified attribute print
-/*     routine. tls_proxy_server_init_print() is meant to be passed as
-/*     a call-back to attr_print(), thusly:
-/*
-/*     ... SEND_ATTR_FUNC(tls_proxy_server_init_print, (const void *) init_props), ...
-/*
-/*     tls_proxy_server_start_print() writes a TLS_SERVER_START_PROPS
-/*     structure to the named stream using the specified attribute print
-/*     routine. tls_proxy_server_start_print() is meant to be passed as
-/*     a call-back to attr_print(), thusly:
-/*
-/*     ... SEND_ATTR_FUNC(tls_proxy_server_start_print, (const void *) start_props), ...
-/* DIAGNOSTICS
-/*     Fatal: out of memory.
-/* LICENSE
-/* .ad
-/* .fi
-/*     The Secure Mailer license must be distributed with this software.
-/* AUTHOR(S)
-/*     Wietse Venema
-/*     Google, Inc.
-/*     111 8th Avenue
-/*     New York, NY 10011, USA
-/*--*/
-
-#ifdef USE_TLS
-
-/* System library. */
-
-#include <sys_defs.h>
-
-/* Utility library */
-
-#include <attr.h>
-
-/* TLS library. */
-
-#include <tls.h>
-#include <tls_proxy.h>
-
-/* tls_proxy_server_init_print - send TLS_SERVER_INIT_PROPS over stream */
-
-int     tls_proxy_server_init_print(ATTR_PRINT_COMMON_FN print_fn, VSTREAM *fp,
-                                           int flags, const void *ptr)
-{
-    const TLS_SERVER_INIT_PROPS *props = (const TLS_SERVER_INIT_PROPS *) ptr;
-    int     ret;
-
-#define STRING_OR_EMPTY(s) ((s) ? (s) : "")
-
-    ret = print_fn(fp, flags | ATTR_FLAG_MORE,
-                  SEND_ATTR_STR(TLS_ATTR_LOG_PARAM,
-                                STRING_OR_EMPTY(props->log_param)),
-                  SEND_ATTR_STR(TLS_ATTR_LOG_LEVEL,
-                                STRING_OR_EMPTY(props->log_level)),
-                  SEND_ATTR_INT(TLS_ATTR_VERIFYDEPTH, props->verifydepth),
-                  SEND_ATTR_STR(TLS_ATTR_CACHE_TYPE,
-                                STRING_OR_EMPTY(props->cache_type)),
-                  SEND_ATTR_INT(TLS_ATTR_SET_SESSID, props->set_sessid),
-                  SEND_ATTR_STR(TLS_ATTR_CHAIN_FILES,
-                                STRING_OR_EMPTY(props->chain_files)),
-                  SEND_ATTR_STR(TLS_ATTR_CERT_FILE,
-                                STRING_OR_EMPTY(props->cert_file)),
-                  SEND_ATTR_STR(TLS_ATTR_KEY_FILE,
-                                STRING_OR_EMPTY(props->key_file)),
-                  SEND_ATTR_STR(TLS_ATTR_DCERT_FILE,
-                                STRING_OR_EMPTY(props->dcert_file)),
-                  SEND_ATTR_STR(TLS_ATTR_DKEY_FILE,
-                                STRING_OR_EMPTY(props->dkey_file)),
-                  SEND_ATTR_STR(TLS_ATTR_ECCERT_FILE,
-                                STRING_OR_EMPTY(props->eccert_file)),
-                  SEND_ATTR_STR(TLS_ATTR_ECKEY_FILE,
-                                STRING_OR_EMPTY(props->eckey_file)),
-                  SEND_ATTR_STR(TLS_ATTR_CAFILE,
-                                STRING_OR_EMPTY(props->CAfile)),
-                  SEND_ATTR_STR(TLS_ATTR_CAPATH,
-                                STRING_OR_EMPTY(props->CApath)),
-                  SEND_ATTR_STR(TLS_ATTR_PROTOCOLS,
-                                STRING_OR_EMPTY(props->protocols)),
-                  SEND_ATTR_STR(TLS_ATTR_EECDH_GRADE,
-                                STRING_OR_EMPTY(props->eecdh_grade)),
-                  SEND_ATTR_STR(TLS_ATTR_DH1K_PARAM_FILE,
-                                STRING_OR_EMPTY(props->dh1024_param_file)),
-                  SEND_ATTR_STR(TLS_ATTR_DH512_PARAM_FILE,
-                                STRING_OR_EMPTY(props->dh512_param_file)),
-                  SEND_ATTR_INT(TLS_ATTR_ASK_CCERT, props->ask_ccert),
-                  SEND_ATTR_STR(TLS_ATTR_MDALG,
-                                STRING_OR_EMPTY(props->mdalg)),
-                  ATTR_TYPE_END);
-    /* Do not flush the stream. */
-    return (ret);
-}
-
-/* tls_proxy_server_start_print - send TLS_SERVER_START_PROPS over stream */
-
-int     tls_proxy_server_start_print(ATTR_PRINT_COMMON_FN print_fn, VSTREAM *fp,
-                                            int flags, const void *ptr)
-{
-    const TLS_SERVER_START_PROPS *props = (const TLS_SERVER_START_PROPS *) ptr;
-    int     ret;
-
-#define STRING_OR_EMPTY(s) ((s) ? (s) : "")
-
-    ret = print_fn(fp, flags | ATTR_FLAG_MORE,
-                  SEND_ATTR_INT(TLS_ATTR_TIMEOUT, props->timeout),
-                  SEND_ATTR_INT(TLS_ATTR_REQUIRECERT, props->requirecert),
-                  SEND_ATTR_STR(TLS_ATTR_SERVERID,
-                                STRING_OR_EMPTY(props->serverid)),
-                  SEND_ATTR_STR(TLS_ATTR_NAMADDR,
-                                STRING_OR_EMPTY(props->namaddr)),
-                  SEND_ATTR_STR(TLS_ATTR_CIPHER_GRADE,
-                                STRING_OR_EMPTY(props->cipher_grade)),
-                  SEND_ATTR_STR(TLS_ATTR_CIPHER_EXCLUSIONS,
-                                STRING_OR_EMPTY(props->cipher_exclusions)),
-                  SEND_ATTR_STR(TLS_ATTR_MDALG,
-                                STRING_OR_EMPTY(props->mdalg)),
-                  ATTR_TYPE_END);
-    /* Do not flush the stream. */
-    return (ret);
-}
-
-#endif
diff --git a/postfix/src/tls/tls_proxy_server_start_proto.c b/postfix/src/tls/tls_proxy_server_start_proto.c
new file mode 100644 (file)
index 0000000..d480ec2
--- /dev/null
@@ -0,0 +1,160 @@
+/*++
+/* NAME
+/*     tls_proxy_server_start_proto 3
+/* SUMMARY
+/*     Support for TLS_SERVER_START structures
+/* SYNOPSIS
+/*     #include <tls_proxy_server_start_proto.h>
+/*
+/*     int     tls_proxy_server_start_print(print_fn, stream, flags, ptr)
+/*     ATTR_PRINT_COMMON_FN print_fn;
+/*     VSTREAM *stream;
+/*     int     flags;
+/*     void    *ptr;
+/*
+/*     int     tls_proxy_server_start_scan(scan_fn, stream, flags, ptr)
+/*     ATTR_SCAN_COMMON_FN scan_fn;
+/*     VSTREAM *stream;
+/*     int     flags;
+/*     void    *ptr;
+/*
+/*     void    tls_proxy_server_start_free(start_props)
+/*     TLS_SERVER_START_PROPS *start_props;
+/* DESCRIPTION
+/*     tls_proxy_server_start_print() writes a TLS_SERVER_START_PROPS
+/*     structure to the named stream using the specified attribute print
+/*     routine. tls_proxy_server_start_print() is meant to be passed as
+/*     a call-back to attr_print(), thusly:
+/*
+/*     ... SEND_ATTR_FUNC(tls_proxy_server_start_print, (const void *) start_props), ...
+/* DIAGNOSTICS
+/*     Fatal: out of memory.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     Google, Inc.
+/*     111 8th Avenue
+/*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#ifdef USE_TLS
+
+/* System library. */
+
+#include <sys_defs.h>
+
+/* Utility library */
+
+#include <argv_attr.h>
+#include <attr.h>
+#include <msg.h>
+
+/* Global library. */
+
+#include <mail_params.h>
+
+/* TLS library. */
+
+#define TLS_INTERNAL
+#include <tls.h>
+#include <tls_proxy_attr.h>
+#include <tls_proxy_server_start_proto.h>
+
+#define STR(x) vstring_str(x)
+#define LEN(x) VSTRING_LEN(x)
+
+/* tls_proxy_server_start_print - send TLS_SERVER_START_PROPS over stream */
+
+int     tls_proxy_server_start_print(ATTR_PRINT_COMMON_FN print_fn, VSTREAM *fp,
+                                            int flags, const void *ptr)
+{
+    const TLS_SERVER_START_PROPS *props = (const TLS_SERVER_START_PROPS *) ptr;
+    int     ret;
+
+#define STRING_OR_EMPTY(s) ((s) ? (s) : "")
+
+    ret = print_fn(fp, flags | ATTR_FLAG_MORE,
+                  SEND_ATTR_INT(TLS_ATTR_TIMEOUT, props->timeout),
+                  SEND_ATTR_INT(TLS_ATTR_ENABLE_RPK, props->enable_rpk),
+                  SEND_ATTR_INT(TLS_ATTR_REQUIRECERT, props->requirecert),
+                  SEND_ATTR_STR(TLS_ATTR_SERVERID,
+                                STRING_OR_EMPTY(props->serverid)),
+                  SEND_ATTR_STR(TLS_ATTR_NAMADDR,
+                                STRING_OR_EMPTY(props->namaddr)),
+                  SEND_ATTR_STR(TLS_ATTR_CIPHER_GRADE,
+                                STRING_OR_EMPTY(props->cipher_grade)),
+                  SEND_ATTR_STR(TLS_ATTR_CIPHER_EXCLUSIONS,
+                                STRING_OR_EMPTY(props->cipher_exclusions)),
+                  SEND_ATTR_STR(TLS_ATTR_MDALG,
+                                STRING_OR_EMPTY(props->mdalg)),
+                  ATTR_TYPE_END);
+    /* Do not flush the stream. */
+    return (ret);
+}
+
+/* tls_proxy_server_start_scan - receive TLS_SERVER_START_PROPS from stream */
+
+int     tls_proxy_server_start_scan(ATTR_SCAN_COMMON_FN scan_fn, VSTREAM *fp,
+                                           int flags, void *ptr)
+{
+    TLS_SERVER_START_PROPS *props
+    = (TLS_SERVER_START_PROPS *) mymalloc(sizeof(*props));
+    int     ret;
+    VSTRING *serverid = vstring_alloc(25);
+    VSTRING *namaddr = vstring_alloc(25);
+    VSTRING *cipher_grade = vstring_alloc(25);
+    VSTRING *cipher_exclusions = vstring_alloc(25);
+    VSTRING *mdalg = vstring_alloc(25);
+
+    /*
+     * Note: memset() is not a portable way to initialize non-integer types.
+     */
+    memset(props, 0, sizeof(*props));
+    props->ctx = 0;
+    props->stream = 0;
+    /* XXX Caller sets fd. */
+    ret = scan_fn(fp, flags | ATTR_FLAG_MORE,
+                 RECV_ATTR_INT(TLS_ATTR_TIMEOUT, &props->timeout),
+                 RECV_ATTR_INT(TLS_ATTR_ENABLE_RPK, &props->enable_rpk),
+                 RECV_ATTR_INT(TLS_ATTR_REQUIRECERT, &props->requirecert),
+                 RECV_ATTR_STR(TLS_ATTR_SERVERID, serverid),
+                 RECV_ATTR_STR(TLS_ATTR_NAMADDR, namaddr),
+                 RECV_ATTR_STR(TLS_ATTR_CIPHER_GRADE, cipher_grade),
+                 RECV_ATTR_STR(TLS_ATTR_CIPHER_EXCLUSIONS,
+                               cipher_exclusions),
+                 RECV_ATTR_STR(TLS_ATTR_MDALG, mdalg),
+                 ATTR_TYPE_END);
+    props->serverid = vstring_export(serverid);
+    props->namaddr = vstring_export(namaddr);
+    props->cipher_grade = vstring_export(cipher_grade);
+    props->cipher_exclusions = vstring_export(cipher_exclusions);
+    props->mdalg = vstring_export(mdalg);
+    ret = (ret == 8 ? 1 : -1);
+    if (ret != 1) {
+       tls_proxy_server_start_free(props);
+       props = 0;
+    }
+    *(TLS_SERVER_START_PROPS **) ptr = props;
+    return (ret);
+}
+
+/* tls_proxy_server_start_free - destroy TLS_SERVER_START_PROPS structure */
+
+void    tls_proxy_server_start_free(TLS_SERVER_START_PROPS *props)
+{
+    /* XXX Caller closes fd. */
+    myfree((void *) props->serverid);
+    myfree((void *) props->namaddr);
+    myfree((void *) props->cipher_grade);
+    myfree((void *) props->cipher_exclusions);
+    myfree((void *) props->mdalg);
+    myfree((void *) props);
+}
+
+#endif
diff --git a/postfix/src/tls/tls_proxy_server_start_proto.h b/postfix/src/tls/tls_proxy_server_start_proto.h
new file mode 100644 (file)
index 0000000..a638651
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef _TLS_PROXY_SERVER_START_PROTO_H_INCLUDED_
+#define _TLS_PROXY_SERVER_START_PROTO_H_INCLUDED_
+
+/*++
+/* NAME
+/*     tls_proxy_server_start_proto 3h
+/* SUMMARY
+/*     TLS_SERVER_START support
+/* SYNOPSIS
+/*     #include <tls_proxy_server_start_proto.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <vstream.h>
+#include <attr.h>
+
+ /*
+  * TLS library.
+  */
+#include <tls.h>
+
+#ifdef USE_TLS
+
+#define TLS_PROXY_SERVER_START_PROPS(props, a1, a2, a3, a4, a5, a6, a7, a8) \
+    (((props)->a1), ((props)->a2), ((props)->a3), \
+    ((props)->a4), ((props)->a5), ((props)->a6), ((props)->a7), \
+    ((props)->a8))
+
+extern int tls_proxy_server_start_print(ATTR_PRINT_COMMON_FN, VSTREAM *, int, const void *);
+extern void tls_proxy_server_start_free(TLS_SERVER_START_PROPS *);
+extern int tls_proxy_server_start_scan(ATTR_SCAN_COMMON_FN, VSTREAM *, int, void *);
+
+#endif                                 /* USE_TLS */
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*
+/*     Wietse Venema
+/*     Google, Inc.
+/*     111 8th Avenue
+/*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif
index 7cd0cf2851f4211a5ad1d4b22b14244bf9051580..7bfbfeb8f27734fd9e1e102329bbebddc341f81d 100644 (file)
   */
 typedef int (*ATTR_SCAN_COMMON_FN) (VSTREAM *, int,...);
 typedef int (*ATTR_SCAN_CUSTOM_FN) (ATTR_SCAN_COMMON_FN, VSTREAM *, int, void *);
+typedef int (*ATTR_VSCAN_COMMON_FN) (VSTREAM *, int, va_list);
+
 typedef int (*ATTR_PRINT_COMMON_FN) (VSTREAM *, int,...);
 typedef int (*ATTR_PRINT_CUSTOM_FN) (ATTR_PRINT_COMMON_FN, VSTREAM *, int, const void *);
+typedef int (*ATTR_VPRINT_COMMON_FN) (VSTREAM *, int, va_list);
 
  /*
   * Attribute types. See attr_scan(3) for documentation.
@@ -46,6 +49,7 @@ typedef int (*ATTR_PRINT_CUSTOM_FN) (ATTR_PRINT_COMMON_FN, VSTREAM *, int, const
 #define ATTR_TYPE_DATA         5       /* Binary data */
 #define ATTR_TYPE_FUNC         6       /* Function pointer */
 #define ATTR_TYPE_STREQ                7       /* Requires (name, value) match */
+#define ATTR_TYPE_BOOL         8       /* Bool */
 
  /*
   * Optional sender-specified grouping for hash or nameval tables.
@@ -63,6 +67,7 @@ typedef int (*ATTR_PRINT_CUSTOM_FN) (ATTR_PRINT_COMMON_FN, VSTREAM *, int, const
   */
 #define SEND_ATTR_INT(name, val)       ATTR_TYPE_INT, CHECK_CPTR(ATTR, char, (name)), CHECK_VAL(ATTR, int, (val))
 #define SEND_ATTR_UINT(name, val)      ATTR_TYPE_INT, CHECK_CPTR(ATTR, char, (name)), CHECK_VAL(ATTR, unsigned, (val))
+#define SEND_ATTR_BOOL(name, val)      ATTR_TYPE_BOOL, CHECK_CPTR(ATTR, char, (name)), CHECK_VAL(ATTR, bool, (val))
 #define SEND_ATTR_STR(name, val)       ATTR_TYPE_STR, CHECK_CPTR(ATTR, char, (name)), CHECK_CPTR(ATTR, char, (val))
 #define SEND_ATTR_HASH(val)            ATTR_TYPE_HASH, CHECK_CPTR(ATTR, HTABLE, (val))
 #define SEND_ATTR_NV(val)              ATTR_TYPE_NV, CHECK_CPTR(ATTR, NVTABLE, (val))
@@ -72,6 +77,7 @@ typedef int (*ATTR_PRINT_CUSTOM_FN) (ATTR_PRINT_COMMON_FN, VSTREAM *, int, const
 
 #define RECV_ATTR_INT(name, val)       ATTR_TYPE_INT, CHECK_CPTR(ATTR, char, (name)), CHECK_PTR(ATTR, int, (val))
 #define RECV_ATTR_UINT(name, val)      ATTR_TYPE_INT, CHECK_CPTR(ATTR, char, (name)), CHECK_PTR(ATTR, unsigned, (val))
+#define RECV_ATTR_BOOL(name, val)      ATTR_TYPE_BOOL, CHECK_CPTR(ATTR, char, (name)), CHECK_PTR(ATTR, bool, (val))
 #define RECV_ATTR_STR(name, val)       ATTR_TYPE_STR, CHECK_CPTR(ATTR, char, (name)), CHECK_PTR(ATTR, VSTRING, (val))
 #define RECV_ATTR_STREQ(name, val)     ATTR_TYPE_STREQ, CHECK_CPTR(ATTR, char, (name)), CHECK_CPTR(ATTR, char, (val))
 #define RECV_ATTR_HASH(val)            ATTR_TYPE_HASH, CHECK_PTR(ATTR, HTABLE, (val))
@@ -84,10 +90,12 @@ CHECK_VAL_HELPER_DCL(ATTR, ssize_t);
 CHECK_VAL_HELPER_DCL(ATTR, long);
 CHECK_VAL_HELPER_DCL(ATTR, int);
 CHECK_VAL_HELPER_DCL(ATTR, unsigned);
+CHECK_VAL_HELPER_DCL(ATTR, bool);
 CHECK_PTR_HELPER_DCL(ATTR, void);
 CHECK_PTR_HELPER_DCL(ATTR, long);
 CHECK_PTR_HELPER_DCL(ATTR, int);
 CHECK_PTR_HELPER_DCL(ATTR, unsigned);
+CHECK_PTR_HELPER_DCL(ATTR, bool);
 CHECK_PTR_HELPER_DCL(ATTR, VSTRING);
 CHECK_PTR_HELPER_DCL(ATTR, NVTABLE);
 CHECK_PTR_HELPER_DCL(ATTR, HTABLE);
@@ -167,6 +175,7 @@ extern int WARN_UNUSED_RESULT attr_vscan_plain(VSTREAM *, int, va_list);
 #define ATTR_NAME_STR          "string"
 #define ATTR_NAME_LONG         "long_number"
 #define ATTR_NAME_DATA         "data"
+#define ATTR_NAME_BOOL         "bool"
 #endif
 
 /* LICENSE
@@ -183,6 +192,9 @@ extern int WARN_UNUSED_RESULT attr_vscan_plain(VSTREAM *, int, va_list);
 /*     Google, Inc.
 /*     111 8th Avenue
 /*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 #endif
index 98c511850f2c66e1b47d72722a75d77b2a9afa56..e4a471420e8a6c9cee8336e19d689e3e98090fd6 100644 (file)
@@ -47,6 +47,8 @@
 /*     The arguments are an attribute name and an integer.
 /* .IP "SEND_ATTR_LONG(const char *name, long value)"
 /*     The arguments are an attribute name and a long integer.
+/* .IP "SEND_ATTR_BOOL(const char *name, bool value)"
+/*     The arguments are an attribute name and a boolean.
 /* .IP "SEND_ATTR_STR(const char *name, const char *value)"
 /*     The arguments are an attribute name and a null-terminated
 /*     string.
@@ -85,6 +87,9 @@
 /*     Google, Inc.
 /*     111 8th Avenue
 /*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 /* System library. */
@@ -114,6 +119,7 @@ int     attr_vprint0(VSTREAM *fp, int flags, va_list ap)
     char   *attr_name;
     unsigned int_val;
     unsigned long long_val;
+    bool    bool_val;
     char   *str_val;
     HTABLE_INFO **ht_info_list;
     HTABLE_INFO **ht;
@@ -152,6 +158,15 @@ int     attr_vprint0(VSTREAM *fp, int flags, va_list ap)
            if (msg_verbose)
                msg_info("send attr %s = %lu", attr_name, long_val);
            break;
+       case ATTR_TYPE_BOOL:
+           attr_name = va_arg(ap, char *);
+           vstream_fwrite(fp, attr_name, strlen(attr_name) + 1);
+           bool_val = va_arg(ap, int);
+           vstream_fprintf(fp, "%u", (unsigned) bool_val);
+           VSTREAM_PUTC('\0', fp);
+           if (msg_verbose)
+               msg_info("send attr %s = %u", attr_name, (unsigned) bool_val);
+           break;
        case ATTR_TYPE_STR:
            attr_name = va_arg(ap, char *);
            vstream_fwrite(fp, attr_name, strlen(attr_name) + 1);
@@ -231,6 +246,7 @@ int     main(int unused_argc, char **argv)
                SEND_ATTR_STR("protocol", "test"),
                SEND_ATTR_INT(ATTR_NAME_INT, 4711),
                SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
+               SEND_ATTR_BOOL(ATTR_NAME_BOOL, true),
                SEND_ATTR_STR(ATTR_NAME_STR, "whoopee"),
                SEND_ATTR_DATA(ATTR_NAME_DATA, strlen("whoopee"), "whoopee"),
                SEND_ATTR_HASH(table),
@@ -240,6 +256,7 @@ int     main(int unused_argc, char **argv)
                SEND_ATTR_STR("protocol", "test"),
                SEND_ATTR_INT(ATTR_NAME_INT, 4711),
                SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
+               SEND_ATTR_BOOL(ATTR_NAME_BOOL, false),
                SEND_ATTR_STR(ATTR_NAME_STR, "whoopee"),
                SEND_ATTR_DATA(ATTR_NAME_DATA, strlen("whoopee"), "whoopee"),
                ATTR_TYPE_END);
index 085ba33ccb03510b39e516a90017a436ce009b12..a0a88645f82c89c02401e0b24e155196d2744aa8 100644 (file)
@@ -47,6 +47,8 @@
 /*     The arguments are an attribute name and an integer.
 /* .IP "SEND_ATTR_LONG(const char *name, long value)"
 /*     The arguments are an attribute name and a long integer.
+/* .IP "SEND_ATTR_BOOL(const char *name, bool value)"
+/*     The arguments are an attribute name and a boolean.
 /* .IP "SEND_ATTR_STR(const char *name, const char *value)"
 /*     The arguments are an attribute name and a null-terminated
 /*     string.
@@ -85,6 +87,9 @@
 /*     Google, Inc.
 /*     111 8th Avenue
 /*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 /* System library. */
@@ -149,6 +154,7 @@ int     attr_vprint64(VSTREAM *fp, int flags, va_list ap)
     char   *attr_name;
     unsigned int_val;
     unsigned long long_val;
+    bool    bool_val;
     char   *str_val;
     HTABLE_INFO **ht_info_list;
     HTABLE_INFO **ht;
@@ -188,6 +194,16 @@ int     attr_vprint64(VSTREAM *fp, int flags, va_list ap)
            if (msg_verbose)
                msg_info("send attr %s = %lu", attr_name, long_val);
            break;
+       case ATTR_TYPE_BOOL:
+           attr_name = va_arg(ap, char *);
+           attr_print64_str(fp, attr_name, strlen(attr_name));
+           bool_val = va_arg(ap, unsigned);
+           VSTREAM_PUTC(':', fp);
+           attr_print64_num(fp, (unsigned) bool_val);
+           VSTREAM_PUTC('\n', fp);
+           if (msg_verbose)
+               msg_info("send attr %s = %u", attr_name, (unsigned) bool_val);
+           break;
        case ATTR_TYPE_STR:
            attr_name = va_arg(ap, char *);
            attr_print64_str(fp, attr_name, strlen(attr_name));
@@ -272,6 +288,7 @@ int     main(int unused_argc, char **argv)
                 SEND_ATTR_STR("protocol", "test"),
                 SEND_ATTR_INT(ATTR_NAME_INT, 4711),
                 SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
+                SEND_ATTR_BOOL(ATTR_NAME_BOOL, true),
                 SEND_ATTR_STR(ATTR_NAME_STR, "whoopee"),
               SEND_ATTR_DATA(ATTR_NAME_DATA, strlen("whoopee"), "whoopee"),
                 SEND_ATTR_HASH(table),
@@ -281,6 +298,7 @@ int     main(int unused_argc, char **argv)
                 SEND_ATTR_STR("protocol", "test"),
                 SEND_ATTR_INT(ATTR_NAME_INT, 4711),
                 SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
+                SEND_ATTR_BOOL(ATTR_NAME_BOOL, false),
                 SEND_ATTR_STR(ATTR_NAME_STR, "whoopee"),
               SEND_ATTR_DATA(ATTR_NAME_DATA, strlen("whoopee"), "whoopee"),
                 ATTR_TYPE_END);
index 7d2d02fdb7b68b96351bd51b8130098d9d2d8641..779755153dec8370bdb3b7997cccce613ad99959 100644 (file)
@@ -47,6 +47,8 @@
 /*     The arguments are an attribute name and an integer.
 /* .IP "SEND_ATTR_LONG(const char *name, long value)"
 /*     The arguments are an attribute name and a long integer.
+/* .IP "SEND_ATTR_BOOL(const char *name, bool value)"
+/*     The arguments are an attribute name and a boolean.
 /* .IP "SEND_ATTR_STR(const char *name, const char *value)"
 /*     The arguments are an attribute name and a null-terminated
 /*     string.
@@ -85,6 +87,9 @@
 /*     Google, Inc.
 /*     111 8th Avenue
 /*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 /* System library. */
@@ -115,6 +120,7 @@ int     attr_vprint_plain(VSTREAM *fp, int flags, va_list ap)
     char   *attr_name;
     unsigned int_val;
     unsigned long long_val;
+    bool    bool_val;
     char   *str_val;
     HTABLE_INFO **ht_info_list;
     HTABLE_INFO **ht;
@@ -149,6 +155,15 @@ int     attr_vprint_plain(VSTREAM *fp, int flags, va_list ap)
            if (msg_verbose)
                msg_info("send attr %s = %lu", attr_name, long_val);
            break;
+       case ATTR_TYPE_BOOL:
+           attr_name = va_arg(ap, char *);
+           bool_val = va_arg(ap, unsigned);
+           vstream_fprintf(fp, "%s=%s\n", attr_name,
+                           bool_val ? "true" : "false");
+           if (msg_verbose)
+               msg_info("send attr %s = %s", attr_name,
+                        bool_val ? "true" : "false");
+           break;
        case ATTR_TYPE_STR:
            attr_name = va_arg(ap, char *);
            str_val = va_arg(ap, char *);
@@ -227,6 +242,7 @@ int     main(int unused_argc, char **argv)
                     SEND_ATTR_STR("protocol", "test"),
                     SEND_ATTR_INT(ATTR_NAME_INT, 4711),
                     SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
+                    SEND_ATTR_BOOL(ATTR_NAME_BOOL, true),
                     SEND_ATTR_STR(ATTR_NAME_STR, "whoopee"),
               SEND_ATTR_DATA(ATTR_NAME_DATA, strlen("whoopee"), "whoopee"),
                     SEND_ATTR_HASH(table),
@@ -236,6 +252,7 @@ int     main(int unused_argc, char **argv)
                     SEND_ATTR_STR("protocol", "test"),
                     SEND_ATTR_INT(ATTR_NAME_INT, 4711),
                     SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
+                    SEND_ATTR_BOOL(ATTR_NAME_BOOL, false),
                     SEND_ATTR_STR(ATTR_NAME_STR, "whoopee"),
               SEND_ATTR_DATA(ATTR_NAME_DATA, strlen("whoopee"), "whoopee"),
                     ATTR_TYPE_END);
index 13aa12504a568a92f26fc1b1cd34e6f1e089e316..5c94e895b3c4fbfd7fc367b67b113a3658eb5341 100644 (file)
 /*     This argument is followed by an attribute name and an integer pointer.
 /* .IP "RECV_ATTR_LONG(const char *name, long *ptr)"
 /*     This argument is followed by an attribute name and a long pointer.
+/* .IP "RECV_ATTR_BOOL(const char *name, bool *ptr)"
+/*     This argument is followed by an attribute name and a pointer to bool.
 /* .IP "RECV_ATTR_STR(const char *name, VSTRING *vp)"
 /*     This argument is followed by an attribute name and a VSTRING pointer.
 /* .IP "RECV_ATTR_STREQ(const char *name, const char *value)"
 /*     Google, Inc.
 /*     111 8th Avenue
 /*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 /* System library. */
@@ -267,6 +272,30 @@ static int attr_scan0_long_number(VSTREAM *fp, unsigned long *ptr,
     return (ch);
 }
 
+/* attr_scan0_bool - pull a boolean value from the input stream */
+
+static int attr_scan0_bool(VSTREAM *fp, bool * ptr, VSTRING *str_buf,
+                                  const char *context)
+{
+    unsigned number;
+    int     ch;
+
+    if ((ch = attr_scan0_number(fp, &number, str_buf, context)) < 0)
+       return (-1);
+    switch (number) {
+    case 0:
+       *ptr = false;
+       return (ch);
+    case 1:
+       *ptr = true;
+       return (ch);
+    default:
+       msg_warn("malformed boolean value from %s while reading %s: %.100s",
+                VSTREAM_PATH(fp), context, STR(str_buf));
+       return (-1);
+    }
+}
+
 /* attr_vscan0 - receive attribute list from stream */
 
 int     attr_vscan0(VSTREAM *fp, int flags, va_list ap)
@@ -278,6 +307,7 @@ int     attr_vscan0(VSTREAM *fp, int flags, va_list ap)
     char   *wanted_name;
     unsigned int *number;
     unsigned long *long_number;
+    bool   *bool_val;
     VSTRING *string;
     HTABLE *hash_table;
     int     ch;
@@ -410,6 +440,12 @@ int     attr_vscan0(VSTREAM *fp, int flags, va_list ap)
                                             "input attribute value")) < 0)
                return (-1);
            break;
+       case ATTR_TYPE_BOOL:
+           bool_val = va_arg(ap, bool *);
+           if ((ch = attr_scan0_bool(fp, bool_val, str_buf,
+                                     "input attribute value")) < 0)
+               return (-1);
+           break;
        case ATTR_TYPE_STR:
            string = va_arg(ap, VSTRING *);
            if ((ch = attr_scan0_string(fp, string,
@@ -533,6 +569,7 @@ int     main(int unused_argc, char **used_argv)
     int     int_val;
     long    long_val;
     long    long_val2;
+    bool    bool_val;
     int     ret;
 
     msg_verbose = 1;
@@ -542,13 +579,15 @@ int     main(int unused_argc, char **used_argv)
                          RECV_ATTR_STREQ("protocol", "test"),
                          RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
                          RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
+                         RECV_ATTR_BOOL(ATTR_NAME_BOOL, &bool_val),
                          RECV_ATTR_STR(ATTR_NAME_STR, str_val),
                          RECV_ATTR_DATA(ATTR_NAME_DATA, data_val),
                          RECV_ATTR_HASH(table),
                          RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val2),
-                         ATTR_TYPE_END)) > 4) {
+                         ATTR_TYPE_END)) > 5) {
        vstream_printf("%s %d\n", ATTR_NAME_INT, int_val);
        vstream_printf("%s %ld\n", ATTR_NAME_LONG, long_val);
+       vstream_printf("%s %d\n", ATTR_NAME_BOOL, bool_val);
        vstream_printf("%s %s\n", ATTR_NAME_STR, STR(str_val));
        vstream_printf("%s %s\n", ATTR_NAME_DATA, STR(str_val));
        ht_info_list = htable_list(table);
@@ -564,11 +603,13 @@ int     main(int unused_argc, char **used_argv)
                          RECV_ATTR_STREQ("protocol", "test"),
                          RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
                          RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
+                         RECV_ATTR_BOOL(ATTR_NAME_BOOL, &bool_val),
                          RECV_ATTR_STR(ATTR_NAME_STR, str_val),
                          RECV_ATTR_DATA(ATTR_NAME_DATA, data_val),
-                         ATTR_TYPE_END)) == 4) {
+                         ATTR_TYPE_END)) == 5) {
        vstream_printf("%s %d\n", ATTR_NAME_INT, int_val);
        vstream_printf("%s %ld\n", ATTR_NAME_LONG, long_val);
+       vstream_printf("%s %d\n", ATTR_NAME_BOOL, bool_val);
        vstream_printf("%s %s\n", ATTR_NAME_STR, STR(str_val));
        vstream_printf("%s %s\n", ATTR_NAME_DATA, STR(data_val));
        ht_info_list = htable_list(table);
index 9055d795da5d666efd6d8dfd1f345b9a01e4c443..8e45506a1e41b295ff64a2781fa7eaea7b8113f7 100644 (file)
@@ -1,6 +1,7 @@
 ./attr_print0: send attr protocol = test
 ./attr_print0: send attr number = 4711
 ./attr_print0: send attr long_number = 1234
+./attr_print0: send attr bool = 1
 ./attr_print0: send attr string = whoopee
 ./attr_print0: send attr data = [data 7 bytes]
 ./attr_print0: send attr name bar-name value bar-value
@@ -9,6 +10,7 @@
 ./attr_print0: send attr protocol = test
 ./attr_print0: send attr number = 4711
 ./attr_print0: send attr long_number = 1234
+./attr_print0: send attr bool = 0
 ./attr_print0: send attr string = whoopee
 ./attr_print0: send attr data = [data 7 bytes]
 ./attr_print0: send attr protocol = not-test
@@ -21,6 +23,9 @@
 ./attr_scan0: unknown_stream: wanted attribute: long_number
 ./attr_scan0: input attribute name: long_number
 ./attr_scan0: input attribute value: 1234
+./attr_scan0: unknown_stream: wanted attribute: bool
+./attr_scan0: input attribute name: bool
+./attr_scan0: input attribute value: 1
 ./attr_scan0: unknown_stream: wanted attribute: string
 ./attr_scan0: input attribute name: string
 ./attr_scan0: input attribute value: whoopee
@@ -51,6 +56,9 @@
 ./attr_scan0: unknown_stream: wanted attribute: long_number
 ./attr_scan0: input attribute name: long_number
 ./attr_scan0: input attribute value: 1234
+./attr_scan0: unknown_stream: wanted attribute: bool
+./attr_scan0: input attribute name: bool
+./attr_scan0: input attribute value: 0
 ./attr_scan0: unknown_stream: wanted attribute: string
 ./attr_scan0: input attribute name: string
 ./attr_scan0: input attribute value: whoopee
@@ -65,6 +73,7 @@
 ./attr_scan0: warning: unexpected protocol not-test from unknown_stream (expected: test)
 number 4711
 long_number 1234
+bool 1
 string whoopee
 data whoopee
 (hash) bar-name bar-value
@@ -72,6 +81,7 @@ data whoopee
 long_number 4321
 number 4711
 long_number 1234
+bool 0
 string whoopee
 data whoopee
 (hash) bar-name bar-value
index 0d9b114c478685c02d1ccae5d8f3fb27e40346bc..5574857bc271dd08aa47e78e1d53ab75a3022f55 100644 (file)
 /*     This argument is followed by an attribute name and an integer pointer.
 /* .IP "RECV_ATTR_LONG(const char *name, long *ptr)"
 /*     This argument is followed by an attribute name and a long pointer.
+/* .IP "RECV_ATTR_BOOL(const char *name, bool *ptr)"
+/*     This argument is followed by an attribute name and a pointer to bool.
 /* .IP "RECV_ATTR_STR(const char *name, VSTRING *vp)"
 /*     This argument is followed by an attribute name and a VSTRING pointer.
 /* .IP "RECV_ATTR_STREQ(const char *name, const char *value)"
 /*     Google, Inc.
 /*     111 8th Avenue
 /*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 /* System library. */
@@ -270,6 +275,30 @@ static int attr_scan64_long_number(VSTREAM *fp, unsigned long *ptr,
     return (ch);
 }
 
+/* attr_scan64_bool - pull a boolean value from the input stream */
+
+static int attr_scan64_bool(VSTREAM *fp, bool * ptr, VSTRING *str_buf,
+                                   const char *context)
+{
+    unsigned number;
+    int     ch;
+
+    if ((ch = attr_scan64_number(fp, &number, str_buf, context)) < 0)
+       return (-1);
+    switch (number) {
+    case 0:
+       *ptr = false;
+       return (ch);
+    case 1:
+       *ptr = true;
+       return (ch);
+    default:
+       msg_warn("malformed boolean value from %s while reading %s: %.100s",
+                VSTREAM_PATH(fp), context, STR(str_buf));
+       return (-1);
+    }
+}
+
 /* attr_vscan64 - receive attribute list from stream */
 
 int     attr_vscan64(VSTREAM *fp, int flags, va_list ap)
@@ -281,6 +310,7 @@ int     attr_vscan64(VSTREAM *fp, int flags, va_list ap)
     char   *wanted_name;
     unsigned int *number;
     unsigned long *long_number;
+    bool   *bool_val;
     VSTRING *string;
     HTABLE *hash_table;
     int     ch;
@@ -439,6 +469,22 @@ int     attr_vscan64(VSTREAM *fp, int flags, va_list ap)
                return (-1);
            }
            break;
+       case ATTR_TYPE_BOOL:
+           if (ch != ':') {
+               msg_warn("missing value for boolean attribute %s from %s",
+                        STR(name_buf), VSTREAM_PATH(fp));
+               return (-1);
+           }
+           bool_val = va_arg(ap, bool *);
+           if ((ch = attr_scan64_bool(fp, bool_val, str_buf,
+                                      "input attribute value")) < 0)
+               return (-1);
+           if (ch != '\n') {
+               msg_warn("multiple values for attribute %s from %s",
+                        STR(name_buf), VSTREAM_PATH(fp));
+               return (-1);
+           }
+           break;
        case ATTR_TYPE_STR:
            if (ch != ':') {
                msg_warn("missing value for string attribute %s from %s",
@@ -602,6 +648,7 @@ int     main(int unused_argc, char **used_argv)
     int     int_val;
     long    long_val;
     long    long_val2;
+    bool    bool_val;
     int     ret;
 
     msg_verbose = 1;
@@ -611,13 +658,15 @@ int     main(int unused_argc, char **used_argv)
                           RECV_ATTR_STREQ("protocol", "test"),
                           RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
                           RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
+                          RECV_ATTR_BOOL(ATTR_NAME_BOOL, &bool_val),
                           RECV_ATTR_STR(ATTR_NAME_STR, str_val),
                           RECV_ATTR_DATA(ATTR_NAME_DATA, data_val),
                           RECV_ATTR_HASH(table),
                           RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val2),
-                          ATTR_TYPE_END)) > 4) {
+                          ATTR_TYPE_END)) > 5) {
        vstream_printf("%s %d\n", ATTR_NAME_INT, int_val);
        vstream_printf("%s %ld\n", ATTR_NAME_LONG, long_val);
+       vstream_printf("%s %d\n", ATTR_NAME_BOOL, bool_val);
        vstream_printf("%s %s\n", ATTR_NAME_STR, STR(str_val));
        vstream_printf("%s %s\n", ATTR_NAME_DATA, STR(data_val));
        ht_info_list = htable_list(table);
@@ -633,11 +682,13 @@ int     main(int unused_argc, char **used_argv)
                           RECV_ATTR_STREQ("protocol", "test"),
                           RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
                           RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
+                          RECV_ATTR_BOOL(ATTR_NAME_BOOL, &bool_val),
                           RECV_ATTR_STR(ATTR_NAME_STR, str_val),
                           RECV_ATTR_DATA(ATTR_NAME_DATA, data_val),
-                          ATTR_TYPE_END)) == 4) {
+                          ATTR_TYPE_END)) == 5) {
        vstream_printf("%s %d\n", ATTR_NAME_INT, int_val);
        vstream_printf("%s %ld\n", ATTR_NAME_LONG, long_val);
+       vstream_printf("%s %d\n", ATTR_NAME_BOOL, bool_val);
        vstream_printf("%s %s\n", ATTR_NAME_STR, STR(str_val));
        vstream_printf("%s %s\n", ATTR_NAME_DATA, STR(data_val));
        ht_info_list = htable_list(table);
index ccf27f12e3fd610f29a728b9aa44f8c70e4ec0fa..82aad3eb6ddaa9eeabe9755e659e6e27b87341bc 100644 (file)
@@ -1,6 +1,7 @@
 ./attr_print64: send attr protocol = test
 ./attr_print64: send attr number = 4711
 ./attr_print64: send attr long_number = 1234
+./attr_print64: send attr bool = 1
 ./attr_print64: send attr string = whoopee
 ./attr_print64: send attr data = [data 7 bytes]
 ./attr_print64: send attr name bar-name value bar-value
@@ -9,6 +10,7 @@
 ./attr_print64: send attr protocol = test
 ./attr_print64: send attr number = 4711
 ./attr_print64: send attr long_number = 1234
+./attr_print64: send attr bool = 0
 ./attr_print64: send attr string = whoopee
 ./attr_print64: send attr data = [data 7 bytes]
 ./attr_print64: send attr protocol = not-test
@@ -21,6 +23,9 @@
 ./attr_scan64: unknown_stream: wanted attribute: long_number
 ./attr_scan64: input attribute name: long_number
 ./attr_scan64: input attribute value: 1234
+./attr_scan64: unknown_stream: wanted attribute: bool
+./attr_scan64: input attribute name: bool
+./attr_scan64: input attribute value: 1
 ./attr_scan64: unknown_stream: wanted attribute: string
 ./attr_scan64: input attribute name: string
 ./attr_scan64: input attribute value: whoopee
@@ -51,6 +56,9 @@
 ./attr_scan64: unknown_stream: wanted attribute: long_number
 ./attr_scan64: input attribute name: long_number
 ./attr_scan64: input attribute value: 1234
+./attr_scan64: unknown_stream: wanted attribute: bool
+./attr_scan64: input attribute name: bool
+./attr_scan64: input attribute value: 0
 ./attr_scan64: unknown_stream: wanted attribute: string
 ./attr_scan64: input attribute name: string
 ./attr_scan64: input attribute value: whoopee
@@ -65,6 +73,7 @@
 ./attr_scan64: warning: unexpected protocol not-test from unknown_stream (expected: test)
 number 4711
 long_number 1234
+bool 1
 string whoopee
 data whoopee
 (hash) bar-name bar-value
@@ -72,6 +81,7 @@ data whoopee
 long_number 4321
 number 4711
 long_number 1234
+bool 0
 string whoopee
 data whoopee
 (hash) bar-name bar-value
index d7e2f6677fcf1857ef981147515c4900feec3984..0e51ca9f8553b5033034435e8806a77a69fc65cb 100644 (file)
 /*     This argument is followed by an attribute name and an integer pointer.
 /* .IP "RECV_ATTR_LONG(const char *name, long *ptr)"
 /*     This argument is followed by an attribute name and a long pointer.
+/* .IP "RECV_ATTR_BOOL(const char *name, bool *ptr)"
+/*     This argument is followed by an attribute name and a pointer to bool.
 /* .IP "RECV_ATTR_STR(const char *name, VSTRING *vp)"
 /*     This argument is followed by an attribute name and a VSTRING pointer.
 /* .IP "RECV_ATTR_STREQ(const char *name, const char *value)"
 /*     Google, Inc.
 /*     111 8th Avenue
 /*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 /* System library. */
@@ -283,6 +288,30 @@ static int attr_scan_plain_long_number(VSTREAM *fp, unsigned long *ptr,
     return (ch);
 }
 
+/* attr_scan_plain_bool - pull a boolean from the input stream */
+
+static int attr_scan_plain_bool(VSTREAM *fp, bool * ptr,
+                                       VSTRING *str_buf,
+                                       int terminator,
+                                       const char *context)
+{
+    int     ch;
+
+    if ((ch = attr_scan_plain_string(fp, str_buf, terminator, context)) < 0) {
+       return (-1);
+    } else if (strcmp(STR(str_buf), "false") == 0) {
+       *ptr = false;
+       return (ch);
+    } else if (strcmp(STR(str_buf), "true") == 0) {
+       *ptr = true;
+       return (ch);
+    } else {
+       msg_warn("malformed boolean value from %s while reading %s: %.100s",
+                VSTREAM_PATH(fp), context, STR(str_buf));
+       return (-1);
+    }
+}
+
 /* attr_vscan_plain - receive attribute list from stream */
 
 int     attr_vscan_plain(VSTREAM *fp, int flags, va_list ap)
@@ -294,6 +323,7 @@ int     attr_vscan_plain(VSTREAM *fp, int flags, va_list ap)
     char   *wanted_name;
     unsigned int *number;
     unsigned long *long_number;
+    bool   *bool_val;
     VSTRING *string;
     HTABLE *hash_table;
     int     ch;
@@ -437,6 +467,17 @@ int     attr_vscan_plain(VSTREAM *fp, int flags, va_list ap)
                                           0, "input attribute value")) < 0)
                return (-1);
            break;
+       case ATTR_TYPE_BOOL:
+           if (ch != '=') {
+               msg_warn("missing value for number attribute %s from %s",
+                        STR(name_buf), VSTREAM_PATH(fp));
+               return (-1);
+           }
+           bool_val = va_arg(ap, bool *);
+           if ((ch = attr_scan_plain_bool(fp, bool_val, str_buf,
+                                          0, "input attribute value")) < 0)
+               return (-1);
+           break;
        case ATTR_TYPE_STR:
            if (ch != '=') {
                msg_warn("missing value for string attribute %s from %s",
@@ -580,6 +621,7 @@ int     main(int unused_argc, char **used_argv)
     int     int_val;
     long    long_val;
     long    long_val2;
+    bool    bool_val;
     int     ret;
 
     msg_verbose = 1;
@@ -589,13 +631,15 @@ int     main(int unused_argc, char **used_argv)
                               RECV_ATTR_STREQ("protocol", "test"),
                               RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
                               RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
+                              RECV_ATTR_BOOL(ATTR_NAME_BOOL, &bool_val),
                               RECV_ATTR_STR(ATTR_NAME_STR, str_val),
                               RECV_ATTR_DATA(ATTR_NAME_DATA, data_val),
                               RECV_ATTR_HASH(table),
                               RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val2),
-                              ATTR_TYPE_END)) > 4) {
+                              ATTR_TYPE_END)) > 5) {
        vstream_printf("%s %d\n", ATTR_NAME_INT, int_val);
        vstream_printf("%s %ld\n", ATTR_NAME_LONG, long_val);
+       vstream_printf("%s %s\n", ATTR_NAME_BOOL, bool_val ? "true" : "false");
        vstream_printf("%s %s\n", ATTR_NAME_STR, STR(str_val));
        vstream_printf("%s %s\n", ATTR_NAME_DATA, STR(data_val));
        ht_info_list = htable_list(table);
@@ -611,11 +655,13 @@ int     main(int unused_argc, char **used_argv)
                               RECV_ATTR_STREQ("protocol", "test"),
                               RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
                               RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
+                              RECV_ATTR_BOOL(ATTR_NAME_BOOL, &bool_val),
                               RECV_ATTR_STR(ATTR_NAME_STR, str_val),
                               RECV_ATTR_DATA(ATTR_NAME_DATA, data_val),
-                              ATTR_TYPE_END)) == 4) {
+                              ATTR_TYPE_END)) == 5) {
        vstream_printf("%s %d\n", ATTR_NAME_INT, int_val);
        vstream_printf("%s %ld\n", ATTR_NAME_LONG, long_val);
+       vstream_printf("%s %s\n", ATTR_NAME_BOOL, bool_val ? "true" : "false");
        vstream_printf("%s %s\n", ATTR_NAME_STR, STR(str_val));
        vstream_printf("%s %s\n", ATTR_NAME_DATA, STR(data_val));
        ht_info_list = htable_list(table);
index 1c0f35809fb2012063b12ab17657519c188ea7f3..c617b8b58d75cd09fca8d876a9dbfced39d13cea 100644 (file)
@@ -1,6 +1,7 @@
 ./attr_print_plain: send attr protocol = test
 ./attr_print_plain: send attr number = 4711
 ./attr_print_plain: send attr long_number = 1234
+./attr_print_plain: send attr bool = true
 ./attr_print_plain: send attr string = whoopee
 ./attr_print_plain: send attr data = [data 7 bytes]
 ./attr_print_plain: send attr name bar-name value bar-value
@@ -9,6 +10,7 @@
 ./attr_print_plain: send attr protocol = test
 ./attr_print_plain: send attr number = 4711
 ./attr_print_plain: send attr long_number = 1234
+./attr_print_plain: send attr bool = false
 ./attr_print_plain: send attr string = whoopee
 ./attr_print_plain: send attr data = [data 7 bytes]
 ./attr_print_plain: send attr protocol = not-test
@@ -21,6 +23,9 @@
 ./attr_scan_plain: unknown_stream: wanted attribute: long_number
 ./attr_scan_plain: input attribute name: long_number
 ./attr_scan_plain: input attribute value: 1234
+./attr_scan_plain: unknown_stream: wanted attribute: bool
+./attr_scan_plain: input attribute name: bool
+./attr_scan_plain: input attribute value: true
 ./attr_scan_plain: unknown_stream: wanted attribute: string
 ./attr_scan_plain: input attribute name: string
 ./attr_scan_plain: input attribute value: whoopee
@@ -51,6 +56,9 @@
 ./attr_scan_plain: unknown_stream: wanted attribute: long_number
 ./attr_scan_plain: input attribute name: long_number
 ./attr_scan_plain: input attribute value: 1234
+./attr_scan_plain: unknown_stream: wanted attribute: bool
+./attr_scan_plain: input attribute name: bool
+./attr_scan_plain: input attribute value: false
 ./attr_scan_plain: unknown_stream: wanted attribute: string
 ./attr_scan_plain: input attribute name: string
 ./attr_scan_plain: input attribute value: whoopee
@@ -65,6 +73,7 @@
 ./attr_scan_plain: warning: unexpected protocol not-test from unknown_stream (expected: test)
 number 4711
 long_number 1234
+bool true
 string whoopee
 data whoopee
 (hash) bar-name bar-value
@@ -72,6 +81,7 @@ data whoopee
 long_number 4321
 number 4711
 long_number 1234
+bool false
 string whoopee
 data whoopee
 (hash) bar-name bar-value