1 /*        $NetBSD: tls_proxy_client_print.c,v 1.5 2025/02/25 19:15:50 christos Exp $      */
2 
3 /*++
4 /* NAME
5 /*        tls_proxy_client_print 3
6 /* SUMMARY
7 /*        write TLS_CLIENT_XXX structures to stream
8 /* SYNOPSIS
9 /*        #include <tls_proxy.h>
10 /*
11 /*        int       tls_proxy_client_param_print(print_fn, stream, flags, ptr)
12 /*        ATTR_PRINT_COMMON_FN print_fn;
13 /*        VSTREAM   *stream;
14 /*        int       flags;
15 /*        const void *ptr;
16 /*
17 /*        int       tls_proxy_client_init_print(print_fn, stream, flags, ptr)
18 /*        ATTR_PRINT_COMMON_FN print_fn;
19 /*        VSTREAM   *stream;
20 /*        int       flags;
21 /*        const void *ptr;
22 /*
23 /*        int       tls_proxy_client_start_print(print_fn, stream, flags, ptr)
24 /*        ATTR_PRINT_COMMON_FN print_fn;
25 /*        VSTREAM   *stream;
26 /*        int       flags;
27 /*        const void *ptr;
28 /* DESCRIPTION
29 /*        tls_proxy_client_param_print() writes a TLS_CLIENT_PARAMS structure to
30 /*        the named stream using the specified attribute print routine.
31 /*        tls_proxy_client_param_print() is meant to be passed as a call-back to
32 /*        attr_print(), thusly:
33 /*
34 /*        SEND_ATTR_FUNC(tls_proxy_client_param_print, (const void *) param), ...
35 /*
36 /*        tls_proxy_client_init_print() writes a full TLS_CLIENT_INIT_PROPS
37 /*        structure to the named stream using the specified attribute
38 /*        print routine. tls_proxy_client_init_print() is meant to
39 /*        be passed as a call-back to attr_print(), thusly:
40 /*
41 /*        SEND_ATTR_FUNC(tls_proxy_client_init_print, (const void *) init_props), ...
42 /*
43 /*        tls_proxy_client_start_print() writes a TLS_CLIENT_START_PROPS
44 /*        structure, without stream or file descriptor members, to
45 /*        the named stream using the specified attribute print routine.
46 /*        tls_proxy_client_start_print() is meant to be passed as a
47 /*        call-back to attr_print(), thusly:
48 /*
49 /*        SEND_ATTR_FUNC(tls_proxy_client_start_print, (const void *) start_props), ...
50 /* DIAGNOSTICS
51 /*        Fatal: out of memory.
52 /* LICENSE
53 /* .ad
54 /* .fi
55 /*        The Secure Mailer license must be distributed with this software.
56 /* AUTHOR(S)
57 /*        Wietse Venema
58 /*        Google, Inc.
59 /*        111 8th Avenue
60 /*        New York, NY 10011, USA
61 /*--*/
62 
63 #ifdef USE_TLS
64 
65 /* System library. */
66 
67 #include <sys_defs.h>
68 
69 /* Utility library */
70 
71 #include <argv_attr.h>
72 #include <attr.h>
73 #include <msg.h>
74 
75 /* Global library. */
76 
77 #include <mail_params.h>
78 
79 /* TLS library. */
80 
81 #include <tls.h>
82 #include <tls_proxy.h>
83 
84 #ifdef USE_TLSRPT
85 #define TLSRPT_WRAPPER_INTERNAL
86 #include <tlsrpt_wrapper.h>
87 #endif
88 
89 #define STR(x) vstring_str(x)
90 #define LEN(x) VSTRING_LEN(x)
91 
92 /* tls_proxy_client_param_print - send TLS_CLIENT_PARAMS over stream */
93 
tls_proxy_client_param_print(ATTR_PRINT_COMMON_FN print_fn,VSTREAM * fp,int flags,const void * ptr)94 int     tls_proxy_client_param_print(ATTR_PRINT_COMMON_FN print_fn, VSTREAM *fp,
95                                                      int flags, const void *ptr)
96 {
97     const TLS_CLIENT_PARAMS *params = (const TLS_CLIENT_PARAMS *) ptr;
98     int     ret;
99 
100     if (msg_verbose)
101           msg_info("begin tls_proxy_client_param_print");
102 
103     ret = print_fn(fp, flags | ATTR_FLAG_MORE,
104                        SEND_ATTR_STR(TLS_ATTR_CNF_FILE, params->tls_cnf_file),
105                        SEND_ATTR_STR(TLS_ATTR_CNF_NAME, params->tls_cnf_name),
106                        SEND_ATTR_STR(VAR_TLS_HIGH_CLIST, params->tls_high_clist),
107                        SEND_ATTR_STR(VAR_TLS_MEDIUM_CLIST,
108                                          params->tls_medium_clist),
109                        SEND_ATTR_STR(VAR_TLS_NULL_CLIST, params->tls_null_clist),
110                        SEND_ATTR_STR(VAR_TLS_EECDH_AUTO, params->tls_eecdh_auto),
111                        SEND_ATTR_STR(VAR_TLS_EECDH_STRONG,
112                                          params->tls_eecdh_strong),
113                        SEND_ATTR_STR(VAR_TLS_EECDH_ULTRA,
114                                          params->tls_eecdh_ultra),
115                        SEND_ATTR_STR(VAR_TLS_FFDHE_AUTO, params->tls_ffdhe_auto),
116                        SEND_ATTR_STR(VAR_TLS_BUG_TWEAKS, params->tls_bug_tweaks),
117                        SEND_ATTR_STR(VAR_TLS_SSL_OPTIONS,
118                                          params->tls_ssl_options),
119                        SEND_ATTR_STR(VAR_TLS_DANE_DIGESTS,
120                                          params->tls_dane_digests),
121                        SEND_ATTR_STR(VAR_TLS_MGR_SERVICE,
122                                          params->tls_mgr_service),
123                        SEND_ATTR_STR(VAR_TLS_TKT_CIPHER, params->tls_tkt_cipher),
124                        SEND_ATTR_INT(VAR_TLS_DAEMON_RAND_BYTES,
125                                          params->tls_daemon_rand_bytes),
126                        SEND_ATTR_INT(VAR_TLS_APPEND_DEF_CA,
127                                          params->tls_append_def_CA),
128                        SEND_ATTR_INT(VAR_TLS_BC_PKEY_FPRINT,
129                                          params->tls_bc_pkey_fprint),
130                        SEND_ATTR_INT(VAR_TLS_PREEMPT_CLIST,
131                                          params->tls_preempt_clist),
132                        SEND_ATTR_INT(VAR_TLS_MULTI_WILDCARD,
133                                          params->tls_multi_wildcard),
134                        ATTR_TYPE_END);
135     /* Do not flush the stream. */
136     if (msg_verbose)
137           msg_info("tls_proxy_client_param_print ret=%d", ret);
138     return (ret);
139 }
140 
141 /* tls_proxy_client_init_print - send TLS_CLIENT_INIT_PROPS over stream */
142 
tls_proxy_client_init_print(ATTR_PRINT_COMMON_FN print_fn,VSTREAM * fp,int flags,const void * ptr)143 int     tls_proxy_client_init_print(ATTR_PRINT_COMMON_FN print_fn, VSTREAM *fp,
144                                                     int flags, const void *ptr)
145 {
146     const TLS_CLIENT_INIT_PROPS *props = (const TLS_CLIENT_INIT_PROPS *) ptr;
147     int     ret;
148 
149     if (msg_verbose)
150           msg_info("begin tls_proxy_client_init_print");
151 
152 #define STRING_OR_EMPTY(s) ((s) ? (s) : "")
153 
154     ret = print_fn(fp, flags | ATTR_FLAG_MORE,
155                        SEND_ATTR_STR(TLS_ATTR_LOG_PARAM,
156                                          STRING_OR_EMPTY(props->log_param)),
157                        SEND_ATTR_STR(TLS_ATTR_LOG_LEVEL,
158                                          STRING_OR_EMPTY(props->log_level)),
159                        SEND_ATTR_INT(TLS_ATTR_VERIFYDEPTH, props->verifydepth),
160                        SEND_ATTR_STR(TLS_ATTR_CACHE_TYPE,
161                                          STRING_OR_EMPTY(props->cache_type)),
162                        SEND_ATTR_STR(TLS_ATTR_CHAIN_FILES,
163                                          STRING_OR_EMPTY(props->chain_files)),
164                        SEND_ATTR_STR(TLS_ATTR_CERT_FILE,
165                                          STRING_OR_EMPTY(props->cert_file)),
166                        SEND_ATTR_STR(TLS_ATTR_KEY_FILE,
167                                          STRING_OR_EMPTY(props->key_file)),
168                        SEND_ATTR_STR(TLS_ATTR_DCERT_FILE,
169                                          STRING_OR_EMPTY(props->dcert_file)),
170                        SEND_ATTR_STR(TLS_ATTR_DKEY_FILE,
171                                          STRING_OR_EMPTY(props->dkey_file)),
172                        SEND_ATTR_STR(TLS_ATTR_ECCERT_FILE,
173                                          STRING_OR_EMPTY(props->eccert_file)),
174                        SEND_ATTR_STR(TLS_ATTR_ECKEY_FILE,
175                                          STRING_OR_EMPTY(props->eckey_file)),
176                        SEND_ATTR_STR(TLS_ATTR_CAFILE,
177                                          STRING_OR_EMPTY(props->CAfile)),
178                        SEND_ATTR_STR(TLS_ATTR_CAPATH,
179                                          STRING_OR_EMPTY(props->CApath)),
180                        SEND_ATTR_STR(TLS_ATTR_MDALG,
181                                          STRING_OR_EMPTY(props->mdalg)),
182                        ATTR_TYPE_END);
183     /* Do not flush the stream. */
184     if (msg_verbose)
185           msg_info("tls_proxy_client_init_print ret=%d", ret);
186     return (ret);
187 }
188 
189 /* tls_proxy_client_tlsa_print - send TLS_TLSA over stream */
190 
tls_proxy_client_tlsa_print(ATTR_PRINT_COMMON_FN print_fn,VSTREAM * fp,int flags,const void * ptr)191 static int tls_proxy_client_tlsa_print(ATTR_PRINT_COMMON_FN print_fn,
192                                           VSTREAM *fp, int flags, const void *ptr)
193 {
194     const TLS_TLSA *head = (const TLS_TLSA *) ptr;
195     const TLS_TLSA *tp;
196     int     count;
197     int     ret;
198 
199     for (tp = head, count = 0; tp != 0; tp = tp->next)
200           ++count;
201     if (msg_verbose)
202           msg_info("tls_proxy_client_tlsa_print count=%d", count);
203 
204     ret = print_fn(fp, flags | ATTR_FLAG_MORE,
205                        SEND_ATTR_INT(TLS_ATTR_COUNT, count),
206                        ATTR_TYPE_END);
207 
208     for (tp = head; ret == 0 && tp != 0; tp = tp->next)
209           ret = print_fn(fp, flags | ATTR_FLAG_MORE,
210                            SEND_ATTR_INT(TLS_ATTR_USAGE, tp->usage),
211                            SEND_ATTR_INT(TLS_ATTR_SELECTOR, tp->selector),
212                            SEND_ATTR_INT(TLS_ATTR_MTYPE, tp->mtype),
213                            SEND_ATTR_DATA(TLS_ATTR_DATA, tp->length, tp->data),
214                            ATTR_TYPE_END);
215 
216     /* Do not flush the stream. */
217     if (msg_verbose)
218           msg_info("tls_proxy_client_tlsa_print ret=%d", count);
219     return (ret);
220 }
221 
222 /* tls_proxy_client_dane_print - send TLS_DANE over stream */
223 
tls_proxy_client_dane_print(ATTR_PRINT_COMMON_FN print_fn,VSTREAM * fp,int flags,const void * ptr)224 static int tls_proxy_client_dane_print(ATTR_PRINT_COMMON_FN print_fn,
225                                           VSTREAM *fp, int flags, const void *ptr)
226 {
227     const TLS_DANE *dane = (const TLS_DANE *) ptr;
228     int     ret;
229 
230     ret = print_fn(fp, flags | ATTR_FLAG_MORE,
231                        SEND_ATTR_INT(TLS_ATTR_DANE, dane != 0),
232                        ATTR_TYPE_END);
233     if (msg_verbose)
234           msg_info("tls_proxy_client_dane_print dane=%d", dane != 0);
235 
236     if (ret == 0 && dane != 0) {
237           /* Send the base_domain and RRs, we don't need the other fields */
238           ret = print_fn(fp, flags | ATTR_FLAG_MORE,
239                            SEND_ATTR_STR(TLS_ATTR_DOMAIN,
240                                              STRING_OR_EMPTY(dane->base_domain)),
241                            SEND_ATTR_FUNC(tls_proxy_client_tlsa_print,
242                                               (const void *) dane->tlsa),
243                            ATTR_TYPE_END);
244     }
245     /* Do not flush the stream. */
246     if (msg_verbose)
247           msg_info("tls_proxy_client_dane_print ret=%d", ret);
248     return (ret);
249 }
250 
251 #ifdef USE_TLSRPT
252 
253 /* tls_proxy_client_tlsrpt_print - send TLSRPT_WRAPPER over stream */
254 
tls_proxy_client_tlsrpt_print(ATTR_PRINT_COMMON_FN print_fn,VSTREAM * fp,int flags,const void * ptr)255 static int tls_proxy_client_tlsrpt_print(ATTR_PRINT_COMMON_FN print_fn,
256                                           VSTREAM *fp, int flags, const void *ptr)
257 {
258     const TLSRPT_WRAPPER *trw = (const TLSRPT_WRAPPER *) ptr;
259     int     have_trw = trw != 0;
260     int     ret;
261 
262     ret = print_fn(fp, flags | ATTR_FLAG_MORE,
263                        SEND_ATTR_INT(TLS_ATTR_TLSRPT, have_trw),
264                        ATTR_TYPE_END);
265     if (msg_verbose)
266           msg_info("tls_proxy_client_tlsrpt_print have_trw=%d", have_trw);
267 
268     if (ret == 0 && have_trw) {
269           ret = print_fn(fp, flags | ATTR_FLAG_MORE,
270                            SEND_ATTR_STR(TRW_RPT_SOCKET_NAME,
271                                              STRING_OR_EMPTY(trw->rpt_socket_name)),
272                            SEND_ATTR_STR(TRW_RPT_POLICY_DOMAIN,
273                                            STRING_OR_EMPTY(trw->rpt_policy_domain)),
274                            SEND_ATTR_STR(TRW_RPT_POLICY_STRING,
275                                            STRING_OR_EMPTY(trw->rpt_policy_string)),
276                            SEND_ATTR_INT(TRW_TLS_POLICY_TYPE,
277                                              (int) trw->tls_policy_type),
278                            SEND_ATTR_FUNC(argv_attr_print,
279                                             (const void *) trw->tls_policy_strings),
280                            SEND_ATTR_STR(TRW_TLS_POLICY_DOMAIN,
281                                            STRING_OR_EMPTY(trw->tls_policy_domain)),
282                            SEND_ATTR_FUNC(argv_attr_print,
283                                               (const void *) trw->mx_host_patterns),
284                            SEND_ATTR_STR(TRW_SRC_MTA_ADDR,
285                                              STRING_OR_EMPTY(trw->snd_mta_addr)),
286                            SEND_ATTR_STR(TRW_DST_MTA_NAME,
287                                              STRING_OR_EMPTY(trw->rcv_mta_name)),
288                            SEND_ATTR_STR(TRW_DST_MTA_ADDR,
289                                              STRING_OR_EMPTY(trw->rcv_mta_addr)),
290                            SEND_ATTR_STR(TRW_DST_MTA_EHLO,
291                                              STRING_OR_EMPTY(trw->rcv_mta_ehlo)),
292                            SEND_ATTR_INT(TRW_SKIP_REUSED_HS,
293                                              trw->skip_reused_hs),
294                            SEND_ATTR_INT(TRW_FLAGS,
295                                              trw->flags),
296                            ATTR_TYPE_END);
297     }
298     /* Do not flush the stream. */
299     if (msg_verbose)
300           msg_info("tls_proxy_client_tlsrpt_print ret=%d", ret);
301     return (ret);
302 }
303 
304 #endif
305 
306 /* tls_proxy_client_start_print - send TLS_CLIENT_START_PROPS over stream */
307 
tls_proxy_client_start_print(ATTR_PRINT_COMMON_FN print_fn,VSTREAM * fp,int flags,const void * ptr)308 int     tls_proxy_client_start_print(ATTR_PRINT_COMMON_FN print_fn,
309                                           VSTREAM *fp, int flags, const void *ptr)
310 {
311     const TLS_CLIENT_START_PROPS *props = (const TLS_CLIENT_START_PROPS *) ptr;
312     int     ret;
313 
314     if (msg_verbose)
315           msg_info("begin tls_proxy_client_start_print");
316 
317 #define STRING_OR_EMPTY(s) ((s) ? (s) : "")
318 
319     ret = print_fn(fp, flags | ATTR_FLAG_MORE,
320                        SEND_ATTR_INT(TLS_ATTR_TIMEOUT, props->timeout),
321                        SEND_ATTR_INT(TLS_ATTR_ENABLE_RPK, props->enable_rpk),
322                        SEND_ATTR_INT(TLS_ATTR_TLS_LEVEL, props->tls_level),
323                        SEND_ATTR_STR(TLS_ATTR_NEXTHOP,
324                                          STRING_OR_EMPTY(props->nexthop)),
325                        SEND_ATTR_STR(TLS_ATTR_HOST,
326                                          STRING_OR_EMPTY(props->host)),
327                        SEND_ATTR_STR(TLS_ATTR_NAMADDR,
328                                          STRING_OR_EMPTY(props->namaddr)),
329                        SEND_ATTR_STR(TLS_ATTR_SNI,
330                                          STRING_OR_EMPTY(props->sni)),
331                        SEND_ATTR_STR(TLS_ATTR_SERVERID,
332                                          STRING_OR_EMPTY(props->serverid)),
333                        SEND_ATTR_STR(TLS_ATTR_HELO,
334                                          STRING_OR_EMPTY(props->helo)),
335                        SEND_ATTR_STR(TLS_ATTR_PROTOCOLS,
336                                          STRING_OR_EMPTY(props->protocols)),
337                        SEND_ATTR_STR(TLS_ATTR_CIPHER_GRADE,
338                                          STRING_OR_EMPTY(props->cipher_grade)),
339                        SEND_ATTR_STR(TLS_ATTR_CIPHER_EXCLUSIONS,
340                                          STRING_OR_EMPTY(props->cipher_exclusions)),
341                        SEND_ATTR_FUNC(argv_attr_print,
342                                           (const void *) props->matchargv),
343                        SEND_ATTR_STR(TLS_ATTR_MDALG,
344                                          STRING_OR_EMPTY(props->mdalg)),
345                        SEND_ATTR_FUNC(tls_proxy_client_dane_print,
346                                           (const void *) props->dane),
347 #ifdef USE_TLSRPT
348                        SEND_ATTR_FUNC(tls_proxy_client_tlsrpt_print,
349                                           (const void *) props->tlsrpt),
350 #endif
351                        SEND_ATTR_STR(TLS_ATTR_FFAIL_TYPE,
352                                          STRING_OR_EMPTY(props->ffail_type)),
353                        ATTR_TYPE_END);
354     /* Do not flush the stream. */
355     if (msg_verbose)
356           msg_info("tls_proxy_client_start_print ret=%d", ret);
357     return (ret);
358 }
359 
360 #endif
361