1 /* $NetBSD: tls_proxy_client_scan.c,v 1.5 2025/02/25 19:15:50 christos Exp $ */
2
3 /*++
4 /* NAME
5 /* tls_proxy_client_scan 3
6 /* SUMMARY
7 /* read TLS_CLIENT_XXX structures from stream
8 /* SYNOPSIS
9 /* #include <tls_proxy.h>
10 /*
11 /* int tls_proxy_client_param_scan(scan_fn, stream, flags, ptr)
12 /* ATTR_SCAN_COMMON_FN scan_fn;
13 /* VSTREAM *stream;
14 /* int flags;
15 /* void *ptr;
16 /*
17 /* void tls_proxy_client_param_free(params)
18 /* TLS_CLIENT_PARAMS *params;
19 /*
20 /* int tls_proxy_client_init_scan(scan_fn, stream, flags, ptr)
21 /* ATTR_SCAN_COMMON_FN scan_fn;
22 /* VSTREAM *stream;
23 /* int flags;
24 /* void *ptr;
25 /*
26 /* void tls_proxy_client_init_free(init_props)
27 /* TLS_CLIENT_INIT_PROPS *init_props;
28 /*
29 /* int tls_proxy_client_start_scan(scan_fn, stream, flags, ptr)
30 /* ATTR_SCAN_COMMON_FN scan_fn;
31 /* VSTREAM *stream;
32 /* int flags;
33 /* void *ptr;
34 /*
35 /* void tls_proxy_client_start_free(start_props)
36 /* TLS_CLIENT_START_PROPS *start_props;
37 /* DESCRIPTION
38 /* tls_proxy_client_param_scan() reads a TLS_CLIENT_PARAMS structure from
39 /* the named stream using the specified attribute scan routine.
40 /* tls_proxy_client_param_scan() is meant to be passed as a call-back
41 /* function to attr_scan(), as shown below.
42 /*
43 /* tls_proxy_client_param_free() destroys a TLS_CLIENT_PARAMS structure
44 /* that was created by tls_proxy_client_param_scan().
45 /*
46 /* TLS_CLIENT_PARAMS *param = 0;
47 /* ...
48 /* ... RECV_ATTR_FUNC(tls_proxy_client_param_scan, (void *) ¶m)
49 /* ...
50 /* if (param != 0)
51 /* tls_proxy_client_param_free(param);
52 /*
53 /* tls_proxy_client_init_scan() reads a full TLS_CLIENT_INIT_PROPS
54 /* structure from the named stream using the specified attribute
55 /* scan routine. tls_proxy_client_init_scan() is meant to be passed
56 /* as a call-back function to attr_scan(), as shown below.
57 /*
58 /* tls_proxy_client_init_free() destroys a TLS_CLIENT_INIT_PROPS
59 /* structure that was created by tls_proxy_client_init_scan().
60 /*
61 /* TLS_CLIENT_INIT_PROPS *init_props = 0;
62 /* ...
63 /* ... RECV_ATTR_FUNC(tls_proxy_client_init_scan, (void *) &init_props)
64 /* ...
65 /* if (init_props != 0)
66 /* tls_proxy_client_init_free(init_props);
67 /*
68 /* tls_proxy_client_start_scan() reads a TLS_CLIENT_START_PROPS
69 /* structure, without the stream of file descriptor members,
70 /* from the named stream using the specified attribute scan
71 /* routine. tls_proxy_client_start_scan() is meant to be passed
72 /* as a call-back function to attr_scan(), as shown below.
73 /*
74 /* tls_proxy_client_start_free() destroys a TLS_CLIENT_START_PROPS
75 /* structure that was created by tls_proxy_client_start_scan().
76 /*
77 /* TLS_CLIENT_START_PROPS *start_props = 0;
78 /* ...
79 /* ... RECV_ATTR_FUNC(tls_proxy_client_start_scan, (void *) &start_props)
80 /* ...
81 /* if (start_props != 0)
82 /* tls_proxy_client_start_free(start_props);
83 /* DIAGNOSTICS
84 /* Fatal: out of memory.
85 /* LICENSE
86 /* .ad
87 /* .fi
88 /* The Secure Mailer license must be distributed with this software.
89 /* AUTHOR(S)
90 /* Wietse Venema
91 /* Google, Inc.
92 /* 111 8th Avenue
93 /* New York, NY 10011, USA
94 /*--*/
95
96 #ifdef USE_TLS
97
98 /* System library. */
99
100 #include <sys_defs.h>
101
102 /* Utility library */
103
104 #include <argv_attr.h>
105 #include <attr.h>
106 #include <msg.h>
107 #include <vstring.h>
108
109 /* Global library. */
110
111 #include <mail_params.h>
112
113 /* TLS library. */
114
115 #define TLS_INTERNAL
116 #include <tls.h>
117 #include <tls_proxy.h>
118 #ifdef USE_TLSRPT
119 #define TLSRPT_WRAPPER_INTERNAL
120 #include <tlsrpt_wrapper.h>
121 #endif
122
123 #define STR(x) vstring_str(x)
124 #define LEN(x) VSTRING_LEN(x)
125
126 /* tls_proxy_client_param_free - destroy TLS_CLIENT_PARAMS structure */
127
tls_proxy_client_param_free(TLS_CLIENT_PARAMS * params)128 void tls_proxy_client_param_free(TLS_CLIENT_PARAMS *params)
129 {
130 myfree(params->tls_cnf_file);
131 myfree(params->tls_cnf_name);
132 myfree(params->tls_high_clist);
133 myfree(params->tls_medium_clist);
134 myfree(params->tls_null_clist);
135 myfree(params->tls_eecdh_auto);
136 myfree(params->tls_eecdh_strong);
137 myfree(params->tls_eecdh_ultra);
138 myfree(params->tls_ffdhe_auto);
139 myfree(params->tls_bug_tweaks);
140 myfree(params->tls_ssl_options);
141 myfree(params->tls_dane_digests);
142 myfree(params->tls_mgr_service);
143 myfree(params->tls_tkt_cipher);
144 myfree((void *) params);
145 }
146
147 /* tls_proxy_client_param_scan - receive TLS_CLIENT_PARAMS from stream */
148
tls_proxy_client_param_scan(ATTR_SCAN_COMMON_FN scan_fn,VSTREAM * fp,int flags,void * ptr)149 int tls_proxy_client_param_scan(ATTR_SCAN_COMMON_FN scan_fn, VSTREAM *fp,
150 int flags, void *ptr)
151 {
152 TLS_CLIENT_PARAMS *params
153 = (TLS_CLIENT_PARAMS *) mymalloc(sizeof(*params));
154 int ret;
155 VSTRING *cnf_file = vstring_alloc(25);
156 VSTRING *cnf_name = vstring_alloc(25);
157 VSTRING *tls_high_clist = vstring_alloc(25);
158 VSTRING *tls_medium_clist = vstring_alloc(25);
159 VSTRING *tls_null_clist = vstring_alloc(25);
160 VSTRING *tls_eecdh_auto = vstring_alloc(25);
161 VSTRING *tls_eecdh_strong = vstring_alloc(25);
162 VSTRING *tls_eecdh_ultra = vstring_alloc(25);
163 VSTRING *tls_ffdhe_auto = vstring_alloc(25);
164 VSTRING *tls_bug_tweaks = vstring_alloc(25);
165 VSTRING *tls_ssl_options = vstring_alloc(25);
166 VSTRING *tls_dane_digests = vstring_alloc(25);
167 VSTRING *tls_mgr_service = vstring_alloc(25);
168 VSTRING *tls_tkt_cipher = vstring_alloc(25);
169
170 if (msg_verbose)
171 msg_info("begin tls_proxy_client_param_scan");
172
173 /*
174 * Note: memset() is not a portable way to initialize non-integer types.
175 */
176 memset(params, 0, sizeof(*params));
177 ret = scan_fn(fp, flags | ATTR_FLAG_MORE,
178 RECV_ATTR_STR(TLS_ATTR_CNF_FILE, cnf_file),
179 RECV_ATTR_STR(TLS_ATTR_CNF_NAME, cnf_name),
180 RECV_ATTR_STR(VAR_TLS_HIGH_CLIST, tls_high_clist),
181 RECV_ATTR_STR(VAR_TLS_MEDIUM_CLIST, tls_medium_clist),
182 RECV_ATTR_STR(VAR_TLS_NULL_CLIST, tls_null_clist),
183 RECV_ATTR_STR(VAR_TLS_EECDH_AUTO, tls_eecdh_auto),
184 RECV_ATTR_STR(VAR_TLS_EECDH_STRONG, tls_eecdh_strong),
185 RECV_ATTR_STR(VAR_TLS_EECDH_ULTRA, tls_eecdh_ultra),
186 RECV_ATTR_STR(VAR_TLS_FFDHE_AUTO, tls_ffdhe_auto),
187 RECV_ATTR_STR(VAR_TLS_BUG_TWEAKS, tls_bug_tweaks),
188 RECV_ATTR_STR(VAR_TLS_SSL_OPTIONS, tls_ssl_options),
189 RECV_ATTR_STR(VAR_TLS_DANE_DIGESTS, tls_dane_digests),
190 RECV_ATTR_STR(VAR_TLS_MGR_SERVICE, tls_mgr_service),
191 RECV_ATTR_STR(VAR_TLS_TKT_CIPHER, tls_tkt_cipher),
192 RECV_ATTR_INT(VAR_TLS_DAEMON_RAND_BYTES,
193 ¶ms->tls_daemon_rand_bytes),
194 RECV_ATTR_INT(VAR_TLS_APPEND_DEF_CA,
195 ¶ms->tls_append_def_CA),
196 RECV_ATTR_INT(VAR_TLS_BC_PKEY_FPRINT,
197 ¶ms->tls_bc_pkey_fprint),
198 RECV_ATTR_INT(VAR_TLS_PREEMPT_CLIST,
199 ¶ms->tls_preempt_clist),
200 RECV_ATTR_INT(VAR_TLS_MULTI_WILDCARD,
201 ¶ms->tls_multi_wildcard),
202 ATTR_TYPE_END);
203 /* Always construct a well-formed structure. */
204 params->tls_cnf_file = vstring_export(cnf_file);
205 params->tls_cnf_name = vstring_export(cnf_name);
206 params->tls_high_clist = vstring_export(tls_high_clist);
207 params->tls_medium_clist = vstring_export(tls_medium_clist);
208 params->tls_null_clist = vstring_export(tls_null_clist);
209 params->tls_eecdh_auto = vstring_export(tls_eecdh_auto);
210 params->tls_eecdh_strong = vstring_export(tls_eecdh_strong);
211 params->tls_eecdh_ultra = vstring_export(tls_eecdh_ultra);
212 params->tls_ffdhe_auto = vstring_export(tls_ffdhe_auto);
213 params->tls_bug_tweaks = vstring_export(tls_bug_tweaks);
214 params->tls_ssl_options = vstring_export(tls_ssl_options);
215 params->tls_dane_digests = vstring_export(tls_dane_digests);
216 params->tls_mgr_service = vstring_export(tls_mgr_service);
217 params->tls_tkt_cipher = vstring_export(tls_tkt_cipher);
218
219 ret = (ret == 19 ? 1 : -1);
220 if (ret != 1) {
221 tls_proxy_client_param_free(params);
222 params = 0;
223 }
224 *(TLS_CLIENT_PARAMS **) ptr = params;
225 if (msg_verbose)
226 msg_info("tls_proxy_client_param_scan ret=%d", ret);
227 return (ret);
228 }
229
230 /* tls_proxy_client_init_free - destroy TLS_CLIENT_INIT_PROPS structure */
231
tls_proxy_client_init_free(TLS_CLIENT_INIT_PROPS * props)232 void tls_proxy_client_init_free(TLS_CLIENT_INIT_PROPS *props)
233 {
234 myfree((void *) props->log_param);
235 myfree((void *) props->log_level);
236 myfree((void *) props->cache_type);
237 myfree((void *) props->chain_files);
238 myfree((void *) props->cert_file);
239 myfree((void *) props->key_file);
240 myfree((void *) props->dcert_file);
241 myfree((void *) props->dkey_file);
242 myfree((void *) props->eccert_file);
243 myfree((void *) props->eckey_file);
244 myfree((void *) props->CAfile);
245 myfree((void *) props->CApath);
246 myfree((void *) props->mdalg);
247 myfree((void *) props);
248 }
249
250 /* tls_proxy_client_init_scan - receive TLS_CLIENT_INIT_PROPS from stream */
251
tls_proxy_client_init_scan(ATTR_SCAN_COMMON_FN scan_fn,VSTREAM * fp,int flags,void * ptr)252 int tls_proxy_client_init_scan(ATTR_SCAN_COMMON_FN scan_fn, VSTREAM *fp,
253 int flags, void *ptr)
254 {
255 TLS_CLIENT_INIT_PROPS *props
256 = (TLS_CLIENT_INIT_PROPS *) mymalloc(sizeof(*props));
257 int ret;
258 VSTRING *log_param = vstring_alloc(25);
259 VSTRING *log_level = vstring_alloc(25);
260 VSTRING *cache_type = vstring_alloc(25);
261 VSTRING *chain_files = vstring_alloc(25);
262 VSTRING *cert_file = vstring_alloc(25);
263 VSTRING *key_file = vstring_alloc(25);
264 VSTRING *dcert_file = vstring_alloc(25);
265 VSTRING *dkey_file = vstring_alloc(25);
266 VSTRING *eccert_file = vstring_alloc(25);
267 VSTRING *eckey_file = vstring_alloc(25);
268 VSTRING *CAfile = vstring_alloc(25);
269 VSTRING *CApath = vstring_alloc(25);
270 VSTRING *mdalg = vstring_alloc(25);
271
272 if (msg_verbose)
273 msg_info("begin tls_proxy_client_init_scan");
274
275 /*
276 * Note: memset() is not a portable way to initialize non-integer types.
277 */
278 memset(props, 0, sizeof(*props));
279 ret = scan_fn(fp, flags | ATTR_FLAG_MORE,
280 RECV_ATTR_STR(TLS_ATTR_LOG_PARAM, log_param),
281 RECV_ATTR_STR(TLS_ATTR_LOG_LEVEL, log_level),
282 RECV_ATTR_INT(TLS_ATTR_VERIFYDEPTH, &props->verifydepth),
283 RECV_ATTR_STR(TLS_ATTR_CACHE_TYPE, cache_type),
284 RECV_ATTR_STR(TLS_ATTR_CHAIN_FILES, chain_files),
285 RECV_ATTR_STR(TLS_ATTR_CERT_FILE, cert_file),
286 RECV_ATTR_STR(TLS_ATTR_KEY_FILE, key_file),
287 RECV_ATTR_STR(TLS_ATTR_DCERT_FILE, dcert_file),
288 RECV_ATTR_STR(TLS_ATTR_DKEY_FILE, dkey_file),
289 RECV_ATTR_STR(TLS_ATTR_ECCERT_FILE, eccert_file),
290 RECV_ATTR_STR(TLS_ATTR_ECKEY_FILE, eckey_file),
291 RECV_ATTR_STR(TLS_ATTR_CAFILE, CAfile),
292 RECV_ATTR_STR(TLS_ATTR_CAPATH, CApath),
293 RECV_ATTR_STR(TLS_ATTR_MDALG, mdalg),
294 ATTR_TYPE_END);
295 /* Always construct a well-formed structure. */
296 props->log_param = vstring_export(log_param);
297 props->log_level = vstring_export(log_level);
298 props->cache_type = vstring_export(cache_type);
299 props->chain_files = vstring_export(chain_files);
300 props->cert_file = vstring_export(cert_file);
301 props->key_file = vstring_export(key_file);
302 props->dcert_file = vstring_export(dcert_file);
303 props->dkey_file = vstring_export(dkey_file);
304 props->eccert_file = vstring_export(eccert_file);
305 props->eckey_file = vstring_export(eckey_file);
306 props->CAfile = vstring_export(CAfile);
307 props->CApath = vstring_export(CApath);
308 props->mdalg = vstring_export(mdalg);
309 ret = (ret == 14 ? 1 : -1);
310 if (ret != 1) {
311 tls_proxy_client_init_free(props);
312 props = 0;
313 }
314 *(TLS_CLIENT_INIT_PROPS **) ptr = props;
315 if (msg_verbose)
316 msg_info("tls_proxy_client_init_scan ret=%d", ret);
317 return (ret);
318 }
319
320 /* tls_proxy_client_start_free - destroy TLS_CLIENT_START_PROPS structure */
321
tls_proxy_client_start_free(TLS_CLIENT_START_PROPS * props)322 void tls_proxy_client_start_free(TLS_CLIENT_START_PROPS *props)
323 {
324 myfree((void *) props->nexthop);
325 myfree((void *) props->host);
326 myfree((void *) props->namaddr);
327 myfree((void *) props->sni);
328 myfree((void *) props->serverid);
329 myfree((void *) props->helo);
330 myfree((void *) props->protocols);
331 myfree((void *) props->cipher_grade);
332 myfree((void *) props->cipher_exclusions);
333 if (props->matchargv)
334 argv_free((ARGV *) props->matchargv);
335 myfree((void *) props->mdalg);
336 if (props->dane)
337 tls_dane_free((TLS_DANE *) props->dane);
338 #ifdef USE_TLSRPT
339 if (props->tlsrpt)
340 trw_free(props->tlsrpt);
341 #endif
342 if (props->ffail_type)
343 myfree(props->ffail_type);
344 myfree((void *) props);
345 }
346
347 /* tls_proxy_client_tlsa_scan - receive TLS_TLSA from stream */
348
tls_proxy_client_tlsa_scan(ATTR_SCAN_COMMON_FN scan_fn,VSTREAM * fp,int flags,void * ptr)349 static int tls_proxy_client_tlsa_scan(ATTR_SCAN_COMMON_FN scan_fn,
350 VSTREAM *fp, int flags, void *ptr)
351 {
352 static VSTRING *data;
353 TLS_TLSA *head;
354 int count;
355 int ret;
356
357 if (data == 0)
358 data = vstring_alloc(64);
359
360 ret = scan_fn(fp, flags | ATTR_FLAG_MORE,
361 RECV_ATTR_INT(TLS_ATTR_COUNT, &count),
362 ATTR_TYPE_END);
363 if (ret == 1 && msg_verbose)
364 msg_info("tls_proxy_client_tlsa_scan count=%d", count);
365
366 for (head = 0; ret == 1 && count > 0; --count) {
367 int u, s, m;
368
369 ret = scan_fn(fp, flags | ATTR_FLAG_MORE,
370 RECV_ATTR_INT(TLS_ATTR_USAGE, &u),
371 RECV_ATTR_INT(TLS_ATTR_SELECTOR, &s),
372 RECV_ATTR_INT(TLS_ATTR_MTYPE, &m),
373 RECV_ATTR_DATA(TLS_ATTR_DATA, data),
374 ATTR_TYPE_END);
375 if (ret == 4) {
376 ret = 1;
377 /* This makes a copy of the static vstring content */
378 head = tlsa_prepend(head, u, s, m, (unsigned char *) STR(data),
379 LEN(data));
380 } else
381 ret = -1;
382 }
383
384 if (ret != 1) {
385 tls_tlsa_free(head);
386 head = 0;
387 }
388 *(TLS_TLSA **) ptr = head;
389 if (msg_verbose)
390 msg_info("tls_proxy_client_tlsa_scan ret=%d", ret);
391 return (ret);
392 }
393
394 /* tls_proxy_client_dane_scan - receive TLS_DANE from stream */
395
tls_proxy_client_dane_scan(ATTR_SCAN_COMMON_FN scan_fn,VSTREAM * fp,int flags,void * ptr)396 static int tls_proxy_client_dane_scan(ATTR_SCAN_COMMON_FN scan_fn,
397 VSTREAM *fp, int flags, void *ptr)
398 {
399 TLS_DANE *dane = 0;
400 int ret;
401 int have_dane = 0;
402
403 ret = scan_fn(fp, flags | ATTR_FLAG_MORE,
404 RECV_ATTR_INT(TLS_ATTR_DANE, &have_dane),
405 ATTR_TYPE_END);
406 if (msg_verbose)
407 msg_info("tls_proxy_client_dane_scan have_dane=%d", have_dane);
408
409 if (ret == 1 && have_dane) {
410 VSTRING *base_domain = vstring_alloc(25);
411
412 dane = tls_dane_alloc();
413 /* We only need the base domain and TLSA RRs */
414 ret = scan_fn(fp, flags | ATTR_FLAG_MORE,
415 RECV_ATTR_STR(TLS_ATTR_DOMAIN, base_domain),
416 RECV_ATTR_FUNC(tls_proxy_client_tlsa_scan,
417 &dane->tlsa),
418 ATTR_TYPE_END);
419
420 /* Always construct a well-formed structure. */
421 dane->base_domain = vstring_export(base_domain);
422 ret = (ret == 2 ? 1 : -1);
423 if (ret != 1) {
424 tls_dane_free(dane);
425 dane = 0;
426 }
427 }
428 *(TLS_DANE **) ptr = dane;
429 if (msg_verbose)
430 msg_info("tls_proxy_client_dane_scan ret=%d", ret);
431 return (ret);
432 }
433
434 #define EXPORT_OR_NULL(str, vstr) do { \
435 if (LEN(vstr) > 0) { \
436 (str) = vstring_export(vstr); \
437 } else { \
438 (str) = 0; \
439 vstring_free(vstr); \
440 } \
441 } while (0)
442
443 #ifdef USE_TLSRPT
444
445 /* tls_proxy_client_tlsrpt_scan - receive TLSRPT_WRAPPER from stream */
446
tls_proxy_client_tlsrpt_scan(ATTR_SCAN_COMMON_FN scan_fn,VSTREAM * fp,int flags,void * ptr)447 static int tls_proxy_client_tlsrpt_scan(ATTR_SCAN_COMMON_FN scan_fn,
448 VSTREAM *fp, int flags, void *ptr)
449 {
450 TLSRPT_WRAPPER *trw = 0;
451 int ret;
452 int have_tlsrpt = 0;
453
454 ret = scan_fn(fp, flags | ATTR_FLAG_MORE,
455 RECV_ATTR_INT(TLS_ATTR_TLSRPT, &have_tlsrpt),
456 ATTR_TYPE_END);
457 if (msg_verbose)
458 msg_info("tls_proxy_client_tlsrpt_scan have_tlsrpt=%d", have_tlsrpt);
459
460 if (ret == 1 && have_tlsrpt) {
461 VSTRING *rpt_socket_name = vstring_alloc(100);
462 VSTRING *rpt_policy_domain = vstring_alloc(100);
463 VSTRING *rpt_policy_string = vstring_alloc(100);
464 int tls_policy_type;
465 ARGV *tls_policy_strings = 0;
466 VSTRING *tls_policy_domain = vstring_alloc(100);
467 ARGV *mx_host_patterns = 0;
468 VSTRING *snd_mta_addr = vstring_alloc(100);
469 VSTRING *rcv_mta_name = vstring_alloc(100);
470 VSTRING *rcv_mta_addr = vstring_alloc(100);
471 VSTRING *rcv_mta_ehlo = vstring_alloc(100);
472 int skip_reused_hs;
473 int trw_flags;
474
475 ret = scan_fn(fp, flags | ATTR_FLAG_MORE,
476 RECV_ATTR_STR(TRW_RPT_SOCKET_NAME, rpt_socket_name),
477 RECV_ATTR_STR(TRW_RPT_POLICY_DOMAIN, rpt_policy_domain),
478 RECV_ATTR_STR(TRW_RPT_POLICY_STRING, rpt_policy_string),
479 RECV_ATTR_INT(TRW_TLS_POLICY_TYPE, &tls_policy_type),
480 RECV_ATTR_FUNC(argv_attr_scan, &tls_policy_strings),
481 RECV_ATTR_STR(TRW_TLS_POLICY_DOMAIN, tls_policy_domain),
482 RECV_ATTR_FUNC(argv_attr_scan, &mx_host_patterns),
483 RECV_ATTR_STR(TRW_SRC_MTA_ADDR, snd_mta_addr),
484 RECV_ATTR_STR(TRW_DST_MTA_NAME, rcv_mta_name),
485 RECV_ATTR_STR(TRW_DST_MTA_ADDR, rcv_mta_addr),
486 RECV_ATTR_STR(TRW_DST_MTA_EHLO, rcv_mta_ehlo),
487 RECV_ATTR_INT(TRW_SKIP_REUSED_HS, &skip_reused_hs),
488 RECV_ATTR_INT(TRW_FLAGS, &trw_flags),
489 ATTR_TYPE_END);
490
491 /* Always construct a well-formed structure. */
492 trw = (TLSRPT_WRAPPER *) mymalloc(sizeof(*trw));
493 trw->rpt_socket_name = vstring_export(rpt_socket_name);
494 trw->rpt_policy_domain = vstring_export(rpt_policy_domain);
495 trw->rpt_policy_string = vstring_export(rpt_policy_string);
496 trw->tls_policy_type = tls_policy_type;
497 trw->tls_policy_strings = tls_policy_strings;
498 EXPORT_OR_NULL(trw->tls_policy_domain, tls_policy_domain);
499 trw->mx_host_patterns = mx_host_patterns;
500 EXPORT_OR_NULL(trw->snd_mta_addr, snd_mta_addr);
501 EXPORT_OR_NULL(trw->rcv_mta_name, rcv_mta_name);
502 EXPORT_OR_NULL(trw->rcv_mta_addr, rcv_mta_addr);
503 EXPORT_OR_NULL(trw->rcv_mta_ehlo, rcv_mta_ehlo);
504 trw->skip_reused_hs = skip_reused_hs;
505 trw->flags = trw_flags;
506 ret = (ret == 13 ? 1 : -1);
507 if (ret != 1) {
508 trw_free(trw);
509 trw = 0;
510 }
511 }
512 *(TLSRPT_WRAPPER **) ptr = trw;
513 if (msg_verbose)
514 msg_info("tls_proxy_client_tlsrpt_scan ret=%d", ret);
515 return (ret);
516 }
517
518 #endif
519
520 /* tls_proxy_client_start_scan - receive TLS_CLIENT_START_PROPS from stream */
521
tls_proxy_client_start_scan(ATTR_SCAN_COMMON_FN scan_fn,VSTREAM * fp,int flags,void * ptr)522 int tls_proxy_client_start_scan(ATTR_SCAN_COMMON_FN scan_fn, VSTREAM *fp,
523 int flags, void *ptr)
524 {
525 TLS_CLIENT_START_PROPS *props
526 = (TLS_CLIENT_START_PROPS *) mymalloc(sizeof(*props));
527 int ret;
528 VSTRING *nexthop = vstring_alloc(25);
529 VSTRING *host = vstring_alloc(25);
530 VSTRING *namaddr = vstring_alloc(25);
531 VSTRING *sni = vstring_alloc(25);
532 VSTRING *serverid = vstring_alloc(25);
533 VSTRING *helo = vstring_alloc(25);
534 VSTRING *protocols = vstring_alloc(25);
535 VSTRING *cipher_grade = vstring_alloc(25);
536 VSTRING *cipher_exclusions = vstring_alloc(25);
537 VSTRING *mdalg = vstring_alloc(25);
538 VSTRING *ffail_type = vstring_alloc(25);
539
540 #ifdef USE_TLSRPT
541 #define EXPECT_START_SCAN_RETURN 17
542 #else
543 #define EXPECT_START_SCAN_RETURN 16
544 #endif
545
546 if (msg_verbose)
547 msg_info("begin tls_proxy_client_start_scan");
548
549 /*
550 * Note: memset() is not a portable way to initialize non-integer types.
551 */
552 memset(props, 0, sizeof(*props));
553 props->ctx = 0;
554 props->stream = 0;
555 props->fd = -1;
556 props->dane = 0; /* scan_fn may return early */
557 ret = scan_fn(fp, flags | ATTR_FLAG_MORE,
558 RECV_ATTR_INT(TLS_ATTR_TIMEOUT, &props->timeout),
559 RECV_ATTR_INT(TLS_ATTR_ENABLE_RPK, &props->enable_rpk),
560 RECV_ATTR_INT(TLS_ATTR_TLS_LEVEL, &props->tls_level),
561 RECV_ATTR_STR(TLS_ATTR_NEXTHOP, nexthop),
562 RECV_ATTR_STR(TLS_ATTR_HOST, host),
563 RECV_ATTR_STR(TLS_ATTR_NAMADDR, namaddr),
564 RECV_ATTR_STR(TLS_ATTR_SNI, sni),
565 RECV_ATTR_STR(TLS_ATTR_SERVERID, serverid),
566 RECV_ATTR_STR(TLS_ATTR_HELO, helo),
567 RECV_ATTR_STR(TLS_ATTR_PROTOCOLS, protocols),
568 RECV_ATTR_STR(TLS_ATTR_CIPHER_GRADE, cipher_grade),
569 RECV_ATTR_STR(TLS_ATTR_CIPHER_EXCLUSIONS,
570 cipher_exclusions),
571 RECV_ATTR_FUNC(argv_attr_scan, &props->matchargv),
572 RECV_ATTR_STR(TLS_ATTR_MDALG, mdalg),
573 RECV_ATTR_FUNC(tls_proxy_client_dane_scan,
574 &props->dane),
575 #ifdef USE_TLSRPT
576 RECV_ATTR_FUNC(tls_proxy_client_tlsrpt_scan,
577 &props->tlsrpt),
578 #endif
579 RECV_ATTR_STR(TLS_ATTR_FFAIL_TYPE, ffail_type),
580 ATTR_TYPE_END);
581 /* Always construct a well-formed structure. */
582 props->nexthop = vstring_export(nexthop);
583 props->host = vstring_export(host);
584 props->namaddr = vstring_export(namaddr);
585 props->sni = vstring_export(sni);
586 props->serverid = vstring_export(serverid);
587 props->helo = vstring_export(helo);
588 props->protocols = vstring_export(protocols);
589 props->cipher_grade = vstring_export(cipher_grade);
590 props->cipher_exclusions = vstring_export(cipher_exclusions);
591 props->mdalg = vstring_export(mdalg);
592 EXPORT_OR_NULL(props->ffail_type, ffail_type);
593 ret = (ret == EXPECT_START_SCAN_RETURN ? 1 : -1);
594 if (ret != 1) {
595 tls_proxy_client_start_free(props);
596 props = 0;
597 }
598 *(TLS_CLIENT_START_PROPS **) ptr = props;
599 if (msg_verbose)
600 msg_info("tls_proxy_client_start_scan ret=%d", ret);
601 return (ret);
602 }
603
604 #endif
605